How to use `bodyParser.raw()` to get raw body?
Asked Answered
T

3

14

I am creating a web API using Express. The feature is to allow API users to send a file to the server.

Here's my app setup code:

var express = require('express');
var path = require('path');
// ...
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

// API routes
var images = require('./routes/api/img');

var app = express();

app.use(bodyParser.raw());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/api', images);

// ...

module.exports = app;

Please notice that I am using app.use(bodyParser.raw());.

How do I get the raw bytes from POST requests?

const express = require('express');
const router = express.Router();

/* POST api/img */
router.post('/img', function(req, res, next) {

  // how do I get the raw bytes?

});

module.exports = router;
Turner answered 19/7, 2016 at 21:33 Comment(1)
Please consider narrowing down your code example to only the parts relevant to your question. In this case I think only some of the app.use lines and the second code snippet are really necessary.Apeak
A
4

The parsed body should be set on req.body.

Keep in mind that middleware is applied in the order you set it with app.use, my understanding is that applying the bodyParser multiple times as you have will attempt to parse the body in that order, leaving you with the result of the last middleware to operate on req.body, i.e. since both bodyParser.json() and bodyParser.raw() both accept any inputs, you will actually end up attempting to parse everything from a Buffer into JSON.

Apeak answered 19/7, 2016 at 21:48 Comment(3)
Is there any way for limiting the bodyParser.raw() middleware to only certain Content-Type?Turner
Excellent question, apparently there is! From the docs1 The raw function takes an option options object that may contain any of the following keys: The type option is used to determine what media type the middleware will parse. This option can be a function or a string... It even accepts wildcards for the mime types, so that should let you get as granular as you need.Apeak
Let me expand then, could you parse only some router endpoints as raw and leave the rest as json?Jopa
D
11

if you want to send a raw data and get with body parser you just configure this way:

app.use(bodyParser.raw({ inflate: true, limit: '100kb', type: 'text/xml' }));

That behavior doesn't corrupt the body content.

Daubigny answered 12/4, 2018 at 13:13 Comment(2)
The important thing is to add the type parameter. The default behavior if type is omitted is to check against type "application/octet-stream", as can be seen here (and is probably unexpected for most users of the library). To match against any content type, use type: "*/*".Angellaangelle
@Angellaangelle saying 'checks against' is misleading. The correct word is 'defaults to'. Thanks for the link. var type = opts.type || "application/octet-stream"Ingenue
S
8

To parse all content types I use:

app.use(
  express.raw({
    inflate: true,
    limit: '50mb',
    type: () => true, // this matches all content types
  })
);

To get the raw body in just a single route:

app.put('/upload', express.raw({ inflate: true, limit: '50mb', type: () => true }), async (req, res) => {
  res.json({ bodySize: req.body.length });
});

In that case note that the previously app.use()'d body parsers (json for example) are executed first - so check that req.body is indeed a Buffer, otherwise a malicious caller could send something like {"length":9999999} with Content-Type: application/json.

Soberminded answered 17/9, 2021 at 18:8 Comment(0)
A
4

The parsed body should be set on req.body.

Keep in mind that middleware is applied in the order you set it with app.use, my understanding is that applying the bodyParser multiple times as you have will attempt to parse the body in that order, leaving you with the result of the last middleware to operate on req.body, i.e. since both bodyParser.json() and bodyParser.raw() both accept any inputs, you will actually end up attempting to parse everything from a Buffer into JSON.

Apeak answered 19/7, 2016 at 21:48 Comment(3)
Is there any way for limiting the bodyParser.raw() middleware to only certain Content-Type?Turner
Excellent question, apparently there is! From the docs1 The raw function takes an option options object that may contain any of the following keys: The type option is used to determine what media type the middleware will parse. This option can be a function or a string... It even accepts wildcards for the mime types, so that should let you get as granular as you need.Apeak
Let me expand then, could you parse only some router endpoints as raw and leave the rest as json?Jopa

© 2022 - 2024 — McMap. All rights reserved.