I'm really new to using REST and Express and I've been following this tutorial on REST API. Here is my app.js code:
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require("mongoose");
var app = express();
var port = parseInt(process.env.PORT, 10) || 3000;
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
Genre = require('./models/genre');
//Connect to mongoose
mongoose.connect('mongodb://localhost/bookstore');
var db = mongoose.connection;
app.listen(port);
console.log('Running on port 3000\n\n');
app.post('/api/genres', function(req, res){
console.log(req.body);
var genre = req.body;
Genre.addGenre(genre, function(err, genre){
if (err) {
console.log(err);
res.send({status: 'something went wrong'});
}else{
res.send({status: 'saved'});
res.json(genre);}
});
});
I'm using Rest Easy on Firefox to check the POST request. The error being generated is "Genre Validation failed" because the body is empty. The schema used for this is defined in the model as:
var mongoose = require("mongoose");
//Genre Schema
var genreSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
create_data:{
type: Date,
default: Date.now
}
});
var Genre = module.exports = mongoose.model('Genre', genreSchema);
// add genre
module.exports.addGenre = function(genre, callback){
Genre.create(genre, callback);
};
I've tried several other popular threads but it still isn't solving the problem. I've tried rearranging the order of how modules are imported and input the data as form using 'application/x-www-form-urlencoded'. Any idea?
Edit: Output of console.log(req.body):
{}
Output of console.log(req) is at jbkb1yxa on jsfiddle.net.(StackOverflow wont let me embed more links since i have low reputation points,apologies.)
Screenshot of REST easy:
http://imgur.com/6QmQqRV
In Postman of the 3 options available for content type select "X-www-form-urlencoded" and it should work.
app.use(bodyParser.urlencoded({
extended: true
}));
See https://github.com/expressjs/body-parser
The 'body-parser' middleware only handles JSON and urlencoded data
In Postman, to test HTTP post actions with a raw JSON data payload, select the raw option and set the following header parameters:
Content-Type: application/json
Also, be sure to wrap any strings used as keys/values in your JSON payload in double quotes.
The body-parser package will parse multi-line raw JSON payloads just fine.
{
"foo": "bar"
}
You need enter correct MIME type in the data section on the REST Easy side:
application/json
It's likely because your call to the database isn't finding what you are looking for. One HUGE pain point for me when I first started learning Mongoose was that I erroneously expected an empty response to be counted as an err but that is not the case.
What is logged if you put console.log(genre) above your res.send and res.json statements?
Also, just wondering, why are you using res.send followed by res.json?
Ok. So I guess it was probably an extension issue. I used the same code to send the POST request using POSTMAN in chrome and now it is working just fine. Earlier even Postman was not working but after I configured chrome to not use proxy server, it works just fine.
Thanks everyone for helping me out.
Related
i am sending a post request from fetch but the nodejs server is not able to access the body from the post request. I tried req.body but it just returns empty brackets.
const express = require('express');
const bodyParser=require("body-parser");
const app = express();
app.use(bodyParser.urlencoded({ extended: true}))
app.use(bodyParser.json());
app.use(express.json());
app.get("/user",function(req,res){
res.send("just Checking");
});
app.post("/user", (req, res) => {
console.log(req.body);
res.send("got the data");
});
app.listen(3000,function(res){
console.log("server is workig a t local host 3000");
});
This is the browser side code
const checking = { name:"badmintion" }
function yo (){
fetch("/user",{
method : "POST",
Headers : {
'Content-Type':'application/json'
},
body: JSON.stringify(checking)
})
}
yo();
In the browser i can see that the data is being sent but i am unable to recieve the in the nodejs server it just shows empty brackets.
Edit: I was able to recreate the server code locally on my machine. I didn't find any issues. I used Postman to send the JSON to the /user route. The issue you might be having is in the front end.
Headers should be lowercase. You have capitalized it:
...
fetch("/user",{
method : "POST",
headers : {
...
}
...
Make sure you're sending data in a JSON format so that express can parse it into object:
To avoid any conflict for (parse json) better that remove body parser completely and try again.
For request, according to stanley, headers set as lowercase. Its will be work.
This tutorial maybe help u:
https://www.geeksforgeeks.org/express-js-express-json-function/amp/
I'm just trying to pass the simplest data possible (at the moment, for test purposes) from client to server with a POST request, but I keep getting empty or undefined logs on req.body.
Server:
//jshint esversion:6
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
mongoose.connect("mongodb://localhost:27017/sandbox", {useNewUrlParser: true});
app.get("/", function(req, res){
res.render("home", {});
})
app.post("/filter", function(req, res){
console.log(req.body);
res.redirect("/");
})
app.listen(3000, function() {
console.log("Server started on port 3000");
});
Client (version 1):
var yourdata = { "name": "The pertinent data"};
console.log(document.body)
$.ajax({
url : "/filter",
type: "POST",
dataType:'text',
data : yourdata,
contentType: "application/json",
});
Client (version 2):
var payload = {data: "The pertinent data"};
var req = new XMLHttpRequest();
req.open('POST', '/filter' , true);
req.send(JSON.stringify(payload))
I added both attempts at a code client-side, but I'm happy with whichever method works. Ideally I'll eventually tap into the payload or data with req.body.payload or something, but at the moment that's just giving me an undefined.
I've looked into quite a few similar posts and usually they were missing the "app.use(bodyParser.urlencoded({extended: true}));" or "app.use(bodyParser.json());" I've tried adding and removing those, changing from true to false, still empty.
The console.log(document.body) on the client script does work, giving me the expected body on the browser console, and the server route is working too, eventually redirecting to home.
I can't see how the issue is something I'm doing wrong on the client side, but oddly enough, if I create a form, with an action to that route, and submit, it seems to send the req.body normally. E.g.:
<form class="form" action="/filter" method="post">
<input name="newName" placeholder="Name">
<button type="submit">Submit</button>
</form>
That does indeed log a JSON object e.g.: { newName: 'John'}
In case it might be relevant, the HTML is the simplest one possible, almost empty, only really doing the pertinent links.
Thanks all in advance!
You need three things:
A request body encoded in some data format
A content-type request header which says which data format you are using
Body parsing middleware that can process that data format
When you submit a form, with no enctype attribute, it will submit the data in URL encoded format with the right content type. This matches the body parsing middleware you have (bodyParser.urlencoded({extended: true})).
1, 2, and 3 are all good.
Note that it does not create a JSON object. The client produces URL encoded data. The server parses that into a JavaScript object. There is no JSON.
Client (version 1):
Here you are passing an object to jQuery so it will URL encode the data in it and would normally set the correct content type.
It is failing because you have contentType: "application/json",.
Since you are falsely claiming that you are sending JSON, bodyParser.urlencoded ignores it.
If you had a JSON body parser in place, it would error because the data is not JSON.
1 and 3 are good, but 2 is a lie.
Remove the contentType property.
Client (version 2):
Now you are JSON encoding the data, but you aren't setting the content type request header, and you don't have body parsing middleware that can handle JSON.
3 is bad, and either 1 or 2 is too.
For the server-side part of your application, you need something that moves the body of the request out of the request string itself to a clear, easy-to-read, and use variable. The express json() method (middleware) does that exactly.
Use the express JSON parser middleware as follows:
app.use(express.json())
Code:
const express = require("express");
// const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
app.use(express.json()); // 👈 here
// ... the rest of your code
Just few notes about the middleware you're using
app.use(bodyParser.urlencoded({extended: true}));
We usually use this middleware to parse the HTML forms data, in other words, it's just like the express middleware express.json(), but the difference here is that it parses the requests which have the content type of HTML forms, while the express.json() converts the ones which have the content-type of application/json.
If you're using express v +4, you don't need the bodyParser package, express has the .urlencoded() and the .json() methods built into the express package itself, you can use them just as express.json() and express.urlencoded().
Tip, you can have both middlewares, the JSON parser, and the HTML form content type parser, when the server receives a content-type JSON, the express.json() middleware will parse the request body, and if the server receives an HTML form content-type the urlencoded middleware will fire:
code example:
const express = require("express");
// const bodyParser = require("body-parser"); ❌ not needed
const mongoose = require("mongoose");
const app = express();
app.use(express.json()); // 👈 here
app.use(express.urlencoded({ extended: true })) // 👈 here
// ... the rest of your code
I'm getting this error when I try to send a Base64 string in a POST request.
POST /saveImage 413 10.564 ms - 1459
PayloadTooLargeError: request entity too large
Already tried
--> app.use(bodyParser.urlencoded({ limit: "50mb", extended: true, parameterLimit: 50000 }))
--> app.use(bodyParser.urlencoded({limit: '50mb'}));
--> app.use(bodyParser({limit: '50mb'}));
Here's my code (api.js class)
const express = require('express');
var app = express();
const router = express.Router();
var Connection = require('tedious').Connection
var Request = require('tedious').Request
var TYPES = require('tedious').TYPES
var multer = require('multer');
....
....
....
router.post('/saveImage', (req, res) => {
request=new Request('SAVE_IMAGE',(err, rowCount, rows)=>{
if(err){
console.log(err);
}
});
request.addParameter("Base64Image", TYPES.Text, req.body.IMG)
connection.callProcedure(request);
});
API CALL (Image class contains a Base64 format image and other fields, but I guess the problem occurs because of the Base64 string length. Small images don't cause any trouble)
create(image: Image) {
return this._http.post('/saveImage', image)
.map(data => data.json()).toPromise()
}
I was having the same error. I tried what you tried it did not work.
I guess you are uploading a file. The simple way to solve this is to not set a Content-Type.
my problem was that I was setting on my headers: Content-Type: application/json and I am [was] using multer (expressjs middle for uploading files).
I have the error whenever I try uploading a file.
So when using postman or making such requests using any tools or libraries like axiosjs or fetch() API do not set content-type.
Once you remove the Content-type it will work. That is what I did
on my code, I have:
const express = require('express');
...
const app = express();
app.use(express.json());
...
...And it is working because I removed Content-Type on my postman headers.
Make sure you are not using Content-Type on the headers.
I would recommend you to use express instead of body-parser, as body-parser got merged back in express a long ago.
I am using this code and it seems to work fine, setting the limit option to 200mb, of both express.json and express.urlencoded
app.use(express.json({ limit: "200mb" }));
app.use(express.urlencoded({ extended: true, limit: "200mb" }));
Source: express.json vs bodyparser.json
I am testing the post method to create a todo item as follows. I am using postman in chrome to simulate the post method call. However, it does not work and gives me the below error. I suspect something is wrong with the way body-parser library is working. What am I doing wrong here?
1 SyntaxError: Unexpected token b
2: at parse (/Users/zack/mydrive/proj/express-demo/node_modules/body-parser/lib/types/json.js:83:15)
3: at /Users/zack/mydrive/proj/express-demo/node_modules/body-parser/lib/read.js:116:18
4: at invokeCallback (/Users/zack/mydrive/proj/express-demo/node_modules/body-parser/node_modules/raw-body/index.js:262:16)
5: at done (/Users/zack/mydrive/proj/express-demo/node_modules/body-parser/node_modules/raw-body/index.js:251:7)
6: at IncomingMessage.onEnd (/Users/zack/mydrive/proj/express-demo/node_modules/body-parser/node_modules/raw-body/index.js:308:7)
7 at IncomingMessage.emit (events.js:104:17)
8 at _stream_readable.js:908:16
Code:
var express = require('express');
var app = express();
var handlebars = require('express-handlebars');
var bodyParser = require('body-parser');
//MIDDLEWARE
app.engine('handlebars', handlebars({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}));
// TODOS
var todos = [
{ body: "take out the trash",completed: false},
{ body: "Do the laundry",completed:true},
{ body: "Make a screencast",completed:false}
]
app.post('/todos', function (req, res){
console.log("todo:", req.body);
var todo = req.body;
console.log("todo:"+todo);
todos.push(todo);
res.status(200).json(todo);
res.send('OK')
})
Further I observe that the problem is because of this line.
app.use(bodyParser.json());
Are you sure you are sending the request as JSON? Make sure you've selected it in Postman - https://imgur.com/j0M7TEX.
If that didn't work, you can try the following -
...
app.post('/todos', function (req, res){
console.log("todo:", req.body);
var todo = req.body;
console.log("todo:"+todo);
todos.push(todo);
// Only try to send a single response.
res.json(todo);
});
It looks like you were trying to send two responses, one containing JSON, and another with text/plain ('Ok').
http://expressjs.com/fr/api.html#res.json
It seems like your program is trying to interpret the post data as json data - and generating an error when it trys to parse the request data which is probably url-encoded.
Perhaps consider sending your data in json format. You will have to set the request headers to indicate the datatype is json. See this answer for an example:
Angular JS POST request not sending JSON data
I just created a new session in postman and it started working. I am not sure if there is a caching effect but it works now. I did not make any code change at all. Posting this as the solution now.
Just don't put quotes on your JSON value.
Not "okay2" but just okay2.
I think that postman adds the quotes himself if needed and in this case creates ""okay2"" which isn't valid JSON.
By the way you can test by clicking on the "row" radio button and write your own JSON.
I have the following Node.js code:
var express = require('express');
var app = express.createServer(express.logger());
app.use(express.bodyParser());
app.post('/', function(request, response) {
response.write(request.body.user);
response.end();
});
Now if I POST something like:
curl -d user=Someone -H Accept:application/json --url http://localhost:5000
I get Someone as expected. Now, what if I want to get the full request body? I tried doing response.write(request.body) but Node.js throws an exception saying "first argument must be a string or Buffer" then goes to an "infinite loop" with an exception that says "Can't set headers after they are sent."; this also true even if I did var reqBody = request.body; and then writing response.write(reqBody).
What's the issue here?
Also, can I just get the raw request without using express.bodyParser()?
Starting from express v4.16 there is no need to require any additional modules, just use the built-in JSON middleware:
app.use(express.json())
Like this:
const express = require('express')
app.use(express.json()) // <==== parse request body as JSON
app.listen(8080)
app.post('/test', (req, res) => {
res.json({requestBody: req.body}) // <==== req.body will be a parsed JSON object
})
Note - body-parser, on which this depends, is already included with express.
Also don't forget to send the header Content-Type: application/json
Express 4.0 and above:
$ npm install --save body-parser
And then in your node app:
const bodyParser = require('body-parser');
app.use(bodyParser);
Express 3.0 and below:
Try passing this in your cURL call:
--header "Content-Type: application/json"
and making sure your data is in JSON format:
{"user":"someone"}
Also, you can use console.dir in your node.js code to see the data inside the object as in the following example:
var express = require('express');
var app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(req, res){
console.dir(req.body);
res.send("test");
});
app.listen(3000);
This other question might also help: How to receive JSON in express node.js POST request?
If you don't want to use the bodyParser check out this other question: https://stackoverflow.com/a/9920700/446681
As of Express 4, the following code appears to do the trick.
Note that you'll need to install body-parser using npm.
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.listen(8888);
app.post('/update', function(req, res) {
console.log(req.body); // the posted data
});
For 2019, you don't need to install body-parser.
You can use:
var express = require('express');
var app = express();
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.listen(8888);
app.post('/update', function(req, res) {
console.log(req.body); // the posted data
});
You should not use body-parser it is deprecated. Try this instead
const express = require('express')
const app = express()
app.use(express.json()) //Notice express.json middleware
The app.use() function is used to mount the specified middleware function(s) at the path which is being specified. It is mostly used to set up middleware for your application.
Now to access the body just do the following
app.post('/', (req, res) => {
console.log(req.body)
})
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())
var port = 9000;
app.post('/post/data', function(req, res) {
console.log('receiving data...');
console.log('body is ',req.body);
res.send(req.body);
});
// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);
This will help you. I assume you are sending body in json.
This can be achieved without body-parser dependency as well, listen to request:data and request:end and return the response on end of request, refer below code sample. ref:https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#request-body
var express = require('express');
var app = express.createServer(express.logger());
app.post('/', function(request, response) {
// push the data to body
var body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
// on end of data, perform necessary action
body = Buffer.concat(body).toString();
response.write(request.body.user);
response.end();
});
});
In my case, I was missing to set the header:
"Content-Type: application/json"
Try this:
response.write(JSON.stringify(request.body));
That will take the object which bodyParser has created for you and turn it back into a string and write it to the response. If you want the exact request body (with the same whitespace, etc), you will need data and end listeners attached to the request before and build up the string chunk by chunk as you can see in the json parsing source code from connect.
The accepted answer only works for a body that is compatible with the JSON format. In general, the body can be accessed using
app.use(
Express.raw({
inflate: true,
limit: '50mb',
type: () => true, // this matches all content types
})
);
like posted here. The req.body has a Buffer type and can be converted into the desired format.
For example into a string via:
let body = req.body.toString()
Or into JSON via:
let body = req.body.toJSON();
If you're lazy enough to read chunks of post data.
you could simply paste below lines
to read json.
Below is for TypeScript similar can be done for JS as well.
app.ts
import bodyParser from "body-parser";
// support application/json type post data
this.app.use(bodyParser.json());
// support application/x-www-form-urlencoded post data
this.app.use(bodyParser.urlencoded({ extended: false }));
In one of your any controller which receives POST call use as shown below
userController.ts
public async POSTUser(_req: Request, _res: Response) {
try {
const onRecord = <UserModel>_req.body;
/* Your business logic */
_res.status(201).send("User Created");
}
else{
_res.status(500).send("Server error");
}
};
_req.body should be parsing you json data into your TS Model.
I'm absolutely new to JS and ES, but what seems to work for me is just this:
JSON.stringify(req.body)
Let me know if there's anything wrong with it!
Install Body Parser by below command
$ npm install --save body-parser
Configure Body Parser
const bodyParser = require('body-parser');
app.use(bodyParser);
app.use(bodyParser.json()); //Make sure u have added this line
app.use(bodyParser.urlencoded({ extended: false }));
What you claim to have "tried doing" is exactly what you wrote in the code that works "as expected" when you invoke it with curl.
The error you're getting doesn't appear to be related to any of the code you've shown us.
If you want to get the raw request, set handlers on request for the data and end events (and, of course, remove any invocations of express.bodyParser()). Note that the data events will occur in chunks, and that unless you set an encoding for the data event those chunks will be buffers, not strings.
You use the following code to log post data:
router.post("/users",function(req,res){
res.send(JSON.stringify(req.body, null, 4));
});