New web dev here, coming form the land of C, and everything is a little new :)
I'm working through some Express learning, and am stuck on getting POST requests to work. I'm using Advanced Rest Client on Chrome to send a POST request and am getting errors, no error number just a simple 'computer says no'.
My app.js:
var express = require('express')
, http = require('http');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.use(express.urlencoded());
app.use(express.json());
});
app.get("/", function(req, res) {
res.send("Hello, Express!");
});
app.get("/hi", function(req, res) {
var message = "Hello :-)";
res.send(message);
});
app.get("/users/:userId", function(req, res) {
res.send("<h1>Hello user #" + req.params.userId);
});
app.post("/users", function(req, res) {
res.send("Creating a new user with name " + req.body.username);
});
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
All the other routes work, just that POST that fails.
EDIT: Additional, I'm using text/html as the content type when I post.
I've restarted the server, ensured the file is saved, rebooted the system etc. I'm guessing the issue is the parsing of the body is failing. Any help would be great, cheers.
express.json() doesn't parse text/html, so you have no req.body inside your route handler, and req.body.username line will throw an error.
I've restarted the server, ensured the file is saved, rebooted the system etc. I'm guessing the issue is the parsing of the body is failing.
Don't guess. Debug and read logs (app.use(express.logger('dev')));
Related
I have an express server in NodeJS. It has a POST request with console.logs inside of it. Where Can I find the console.logs?
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
app.use(express.json());
const PORT = 5000;
app.get('/', (req, res) => {
console.log("this appears in the browser");
});
app.post('/login', (req, res) => {
console.log("where do I see this text??");
});
app.listen(PORT, '0.0.0.0', function() {
console.log("Server started (this text appears in the terminal)");
});
I'm running the server from Command Prompt. console.logs that aren't within a request appear in it. Where do the console.logs in the POST request function appear? I ask because I would like to see what's going on with the logic inside a more sophisticated POST request.
When you run the Node.js server directly from cmd, it should start the server and listening to the port specified. Now, when you start to hit the route/s all the console.log o/p to the terminal window not to the browser console window. Check the image for reference.
It will appear in the same terminal that you put the server to run.
I found my question was asked a year ago here app.post() not working with Express but the code written there is outdated (the way bodyparser was added doesn't work anymore as well as function mentioned below) plus the asker never chose an answer so the question was never solved.
Here's my code
const express = require("express");
const db = require("mysql");
const app = express();
const bodyParser = require("body-parser");
const multer = require("multer"); // v1.0.5
const upload = multer(); // for parsing multipart/form-data
const http = require("http");
const path = require("path");
app.set("view engine", "jade");
app.set("views", path.join(__dirname));
console.log("before");
app.listen(8000, () => {
console.log("Server started!");
console.log("within");
});
console.log("after");
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.post("/", function(req, res) {
console.log("hit here in post");
res.render("index.jade", {});
console.log("hit here in post");
res.json({ name: "John" });
res.status(500).json({ error: "message" });
res.end();
});
app.get("/", function(req, res) {
res.render("index.jade", {});
console.log("hit here in get");
console.log(req.body);
});
Here's the output.
before
after
Server started!
within
hit here in get
{}
I even tried to wrap the app sets and uses in app.configure like the asker of the other question to see if that was the issue but that configure function doesn't seem to exist anymore because I got an error about it.
Also I should probably note. My routing here is correct. I haven't made a views subfolder yet so that's why I have it written as it is.
Update
I think I may have spotted the issue but I don't understand why it's occurring. In the network tab of the browser I see that GET is getting 404 error because of a favicon.ico request but I don't understand where that request is coming from. I've seen the serve-favicon npm module to support it but didn't want to added because I never intended to add a favicon image to my server. I don't even understand how that would work.
Reply to last comment by James
What do you mean by I configure the middleware after it has started? Are you referring to the fact that the post method is written after port listening has started? Also if that's the reason why post isn't executing how come the get method executes regardless of that? I'm not holding back any server code aside from code I currently have commented out for the moment but that code I posted is my main index.js file and it's the only file I modified from the standard npm init project. I haven't setup any routes because I don't see the need to do so (even when I add react since my project is simple in concept of communication between reactjs, nodejs and a database "hence my frustration") which is why I'm trying to have get and post only access the root directory.
favicon is automatically requested by the browser. it is the icon used in the browser tab or url address bar
Add this, before app.get():
app.all('/', function(req, res, next) {
console.log({method: req.method, url: req.url});
next();
});
I was using express route like this and I want my urls to contain query strings initially.
app.get('/', function(req, res){
res.render('index', {});
});
app.get('/us01', function(req, res){
console.log('query: '+JSON.stringify(req.query));
res.render('templates/us01', {});
});
app.get('/benchmark', function(req, res){
res.render('templates/benchmark', {});
});
However, I never get my query strings printed no matter what query strings I append after /us01. For example, "localhost:9200/us01?a=1" req.query should get me {a:1}, correct? Is this a common thing? What am I missing here?
My app.js
"use strict";
var express = require('express');
var expApp = express();
var http = require('http').Server(expApp);
var path = require('path');
var bodyParser = require('body-parser');
// all environments
expApp.set('port', process.env.PORT || 5555);
expApp.set('views', __dirname + '/views');
expApp.set('view engine', 'ejs');
expApp.use(bodyParser.urlencoded({ extended: true }));
expApp.use(bodyParser.json());
expApp.use(express.static(path.join(__dirname, 'public')));
//----------------ROUTES--------------------------//
require("./routes/route.js")(expApp);
http.listen(expApp.get('port'), function(){
console.log('Node-Server listening on port ' + expApp.get('port'));
});
My indexController.js has :
$stateProvider
.state('us01', {
url: '/us01',
templateUrl: '/us01'
}).state('benchmark', {
url: '/benchmark',
templateUrl: '/benchmark'
})....
This simple code:
const express = require('express');
const app = express();
app.get('/us01', function(req, res) {
console.log(req.query);
res.send("ok");
});
app.listen(80);
Then, accessed by http://localhost/us01?a=1 produces this output in the console:
{ a: '1' }
Or, if I use:
console.log('query: ' + JSON.stringify(req.query));
Then, I see this in the console:
query: {"a":"1"}
So, clearly something else is wrong in your code.
"localhost:9200/us01?a=1" req.query should get me {a:1}, correct?
It should get you query: {"a":"1"} if the code you show is running on port 9200 on localhost.
Is this a common thing?
No. Something other than the code you show is busted because there's nothing wrong with just that bit of code.
What am I missing here?
Things to examine:
Are you getting any output in the console when you hit any of your expected routes?
Can you prove that your server is running and your browser is hitting your route handlers?
If you just do console.log(req.query), what output do you get?
Are you absolutely sure that you've killed any prior servers and started the server that corresponds to the code you show. People sometimes get fooled by a prior version of the server that is still running and doesn't actually contain the code they think they are running.
Are you 100% sure you are running your server on the desired port that matches the port in the URL you are using.
When all else fails, sometimes a computer reboot will make sure no prior versions of anything are still running.
I have a node app on heroku that is using express to act as a REST API.
On thursday and friday of last week, it was working just fine, when i would post using REST Easy through firefox. I hope on Saturday morning and the request would no longer send the data.
I can see the data in the payload of the request, but it never makes it to the request body.
import express from 'express';
import bodyParser from 'body-parser';
let app = express();
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
app.set('port', (process.env.PORT || 5000));
let router = express.Router();
router.post('/', (req, res) => {
res.json(req.body);
});
app.use('/api', router);
app.listen(app.get('port'), () => {
console.log('Node app is running on port', app.get('port'));
});
All i get back is an empty object, which i believe is the by product of the bodyParser.json()
I am sending it as form data using application/x-www-form-urlencoded, and i have even tried checking to make sure it wasn't parsed twice, which would cause the key to be the body data using
try {
req.body = JSON.parse(Object.keys(req.body)[0])
} catch (err) {
req.body = req.body
}
I am completely stumped at this point, any thoughts?
Looks like it was something with that addon, just stopped working overnight. Had to download chrome and use Advance Rest Client, and that showed the data coming through. Thanks for jumping on the question #p0k8_
I have the following server file, using express:
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
app.listen(port);
console.log('Listening on port: ' + port);
// get an instance of router
var router = express.Router();
app.use('/', router);
app.use(express.static(__dirname + "/"));
// route middle-ware that will happen on every request
router.use(function(req, res, next) {
// log each request to the console
console.log(req.method, req.url + " logging all requests");
// continue doing what we were doing and go to the route
next();
});
// home page route for port 8080, gets executed when entering localhost:8080
// and redirects to index.html (correctly and as expected)
router.get('/', function(req, res) {
console.log("routing from route")
res.redirect('index.html');
});
// This gets executed when my url is: http://localhost:8080/test
// and redirects to index.html (the questions is why!? I thought
// all the requests to root route would be caught by the router instance
app.get('*', function(req, res){
console.log('redirecting to index.html');
res.redirect('/index.html');
});
Looking at the code above and my comments, I cannot understand why
app.get('*', function(){...})
does not get executed when URL is
localhost:8080/index.html but gets executed when URL is localhost:8080/test
Even though, this is the behavior that I was hoping for, I'm not sure why this works?
I don't have a "test.html" page in the root.
One other thing, the index.html does load other scripts, so I expected
app.get('*', function(){...})
to get executed for such get requests too, as it is supposed to be the catch all, but it does not.
Does app.use('/', router) mean that any route that has single character "/" should be handled by Router instance (as long as not a static file)? so "http:localhost:8080" gets interpreted as "http://localhost:8080/"?
I would appreciate any explanation.
This line-
app.use(express.static(__dirname + "/"));
will run first. It will see that index.html exists and serve that file statically.