I know about body-parser and what it does. I'm curious to know where is data in request while using express. In which format does is exist before body-parser parse input.
// parse urlencoded types to JSON
app.use(bodyParser.urlencoded({
extended: true
}));
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }));
Where will be data if none of these is used? In which format will it be available?
This is pretty thoroughly covered in the Node documentation.
The request object that's passed in to a handler implements the ReadableStream interface. This stream can be listened to or piped elsewhere just like any other stream. We can grab the data right out of the stream by listening to the stream's 'data' and 'end' events.
Express is really applying extensions to the Node.js HTTP server features, including extending the native Request and Response objects. Therefore, you can likewise treat the Express request just like a native request object as well
A POST request is made to a specific path (with optional query parameters). The body of the request is where the POST data is put. Express by default reads the headers of the request, but does not read the body of the request. It is the body-parser middleware's job to read and parse that request body so that its data is easily available to you.
Where will be data if none of these is used? In which format will it be available?
So, if you don't have the body-parser middleware installed or don't have a version of the middleware that matches the format of the data, then the body will still be in the incoming request stream, waiting to be read. The req parameter to the request is a readable stream. The data will be waiting to be read in that stream.
The format will be whatever the content-type header in the request says the format will be. For a classic form post, it is typically application/x-www-form-urlencoded, but it can be set to other types such as application/json. It is the requester who decides what content-type to set and then they must encode the data in the body according to that standard.
For things like file uploads, other content types such as multipart/form-data may be used.
Related
I have a confusion while using the bodyparser.Why do we actually need bodyparser when we have json.stringify(to convert object to string) and json.parse(to convert JSON to object)
is it because using it in our app.use() automatically applies the middleware during the interchange of data between client and the server? and we don't need to specify each time when the sending the data from client to server and vice versa?
and if it is so what is the difference between urlencoded and json in bodyparser?
Yes, you are correct. Body-parser is a middleware that automatically parses incoming request bodies and makes the data available in req.body property. It eliminates the need to manually parse the request body each time a request is made, saving time and reducing the risk of bugs.
The difference between urlencoded and json in body-parser is the format of the incoming request body. urlencoded is used when the request body is encoded as URL-encoded strings (i.e. x-www-form-urlencoded) while JSON is used when the request body is in JSON format. By using both, you can handle different types of request bodies.
Why do we actually need bodyparser when we have json.stringify(to convert object to string)
The body parser is also responsible for reading the data from the network stream of the HTTP request in the first place. You can't parse data until you have it.
what is the difference between urlencoded and json in bodyparser?
They parse bodies written in different data formats. The urlencoded format is the default encoding format for a <form>.
We have a method res.json to send file in NodeJs but what would happen if we send a json file using res.send. What will be the consequences and why should we avoid doing this thing?
from express documentation:
res.json([body])
Sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a JSON string using JSON.stringify().
The parameter can be any JSON type, including object, array, string, Boolean, number, or null, and you can also use it to convert other values to JSON.
res.send([body])
Sends the HTTP response.
The body parameter can be a Buffer object, a String, an object, Boolean, or an Array.
This method performs many useful tasks for simple non-streaming responses: For example, it automatically assigns the Content-Length HTTP response header field (unless previously defined) and provides automatic HEAD and HTTP cache freshness support.
When the parameter is a Buffer object, the method sets the Content-Type response header field to “application/octet-stream”, unless previously defined.
When the parameter is a String, the method sets the Content-Type to “text/html”.
When the parameter is an Array or Object, Express responds with the JSON representation.
I assume you are talking about ExpressJS:
Whenever an Express application server receives an HTTP request, it will provide the developer with an object, commonly referred to as res. For example,
Example
app.get('/test', (req, res) => {
// use req and res here
})
The res object basically refers to the response that'll be sent out as part of this API call.
res.send:
The res.send function sets the content type to text/Html which means that the client will now treat it as text. It then returns the response to the client.
res.json:
The res.json function on the other handsets the content-type header to application/JSON so that the client treats the response string as a valid JSON object. It also then returns the response to the client.
conclusion:
With res.send you have to take care of converting it to a JSON object if needed, whereas with res.json this is done automatically.
I have always sent files along with form data by having the action attribute and multipart enctypes to my html forms. Recently I needed to use fetch to send a form and used the new FormData() can read all my fields and file of a given html form. But on the nodejs end, req.files returns null. When I use form action attribute, it works perfectly.
Client End
let formData = new FormData(document.getElementById('additem'));
let response = await fetch(`${window.location.href}/inventory`, {
method: "POST",
body: formData
});
On the server end I am just using express-bodyparser (which is default now) and am trying to access the files with req.files;
I know I can use multer or formidable but I was wondering if there's a way to make it work with what I have atm.
Thanks.
On the server end I am just using express-bodyparser (which is default now) and am trying to access the files with req.files; I know I can use multer or formidable but I was wondering if there's a way to make it work with what I have atm.
No, there isn't. FormData objects generate multipart bodies.
See the documentation for body parser
This does not handle multipart bodies, due to their complex and
typically large nature. For multipart bodies, you may be interested in
the following modules:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
where are your Content-Type if you are going to send a file you need to specified
on them headers, by default the content-type is application/json
there is good example at the Mozilla Docs: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
I'm using node.js with express.
I have my home page which after loading will hit my REST endpoint (PUT) sending some json data.I'm not gziping the data while sending to REST end point.But at my endpoint I want it in gzip form is it possible ? If so how ?
Note: I want to use content-encoding from client. I neither want to gzip it on client nor on server. (Not even as a middleware as that is also on server)
You can add a middleware in your express server. Any requests hitting your endpoint will go through this middleware, and within your middleware, you can gzipping your data, this zipped data get forwarded to your endpoint.
If you need to automatically compress/decompress data coming or going through the request one way to use is request-promise node module
import rp = require("request-promise");
const requestOptions: rp.Options = {
uri: "my-endpoint",
gzip: true,
method: "GET",
encoding: "UTF-8",
headers: {
Accept: "*/*",
Authorization: `xxx--token`
}
};
rp(requestOptions)
.then((response: any) =>
{ // ..your logic to process the response.. }
gzip - if true, add an Accept-Encoding header to request compressed content encodings from the server (if not already present) and decode supported content encodings in the response. Note: Automatic decoding of the response content is performed on the body data returned through request (both through the request stream and passed to the callback function) but is not performed on the response stream (available from the response event) which is the unmodified http.IncomingMessage object which may contain compressed data
request-promise-options
I have created an API end point to handle http POST requests from a client.
Currently Express framework and bodyParser to handle the request bodies. How do I use the body-parser to take care of cases where request bodies that may either be gzipped compressed Json objects OR plain Json objects.
bodyParser json parser will only handle requests when the Content-Type in request header and type below are both same.
bodyParser.json({type: 'application/gzip'})
bodyParser.json({type: 'application/json'})
Is there a way bodyParser can handle both cases in the API end point ?
Any help is appreciated.
Actually, no worries
I am able to figure out how will that happen.
I can have bodyParser handle both the gzip and json POST payload bodies.
app.use(bodyParser.json({type: 'application/gzip'}))
app.use(bodyParser.json({type: 'application/json'}))
The first parser will handle if Content-Type in request header is application/gzip
The second will handle if if Content-Type in request header is application/json
For me following worked:
app.use(bodyParser.json({type: ['application/json', 'application/gzip']}))