【问题标题】:How to use `bodyParser.raw()` to get raw body?如何使用 `bodyParser.raw()` 获取原始身体?
【发布时间】:2016-11-22 23:02:57
【问题描述】:

我正在使用 Express 创建一个 Web API。 该功能是允许 API 用户向服务器发送文件。

这是我的应用设置代码:

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;

请注意我使用的是app.use(bodyParser.raw());

如何从 POST 请求中获取原始字节?

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;

【问题讨论】:

  • 请考虑将您的代码示例缩小到仅与您的问题相关的部分。在这种情况下,我认为只有一些 app.use 行和第二个代码 sn-p 是真正必要的。

标签: node.js express body-parser


【解决方案1】:

解析后的正文应设置为req.body

请记住,中间件是按照您使用app.use 设置的顺序应用的,我的理解是,多次应用 bodyParser 会尝试按该顺序解析正文,给您留下结果最后一个在 req.body 上运行的中间件,即由于 bodyParser.json() 和 bodyParser.raw() 都接受任何输入,您实际上最终会尝试将所有内容从 Buffer 解析为 JSON。

【讨论】:

  • 有什么方法可以将bodyParser.raw() 中间件限制为仅特定的Content-Type
  • 很好的问题,显然有!来自 docs1 原始函数接受一个选项选项对象,该对象可能包含以下任何键: type 选项用于确定中间件将解析的媒体类型。这个选项可以是一个函数或一个字符串......它甚至可以接受 MIME 类型的通配符,这样你就可以根据需要获得尽可能细的粒度。
  • 那么让我扩展一下,你能不能只解析一些路由器端点为原始的,其余的为json?
【解决方案2】:

如果您想发送原始数据并使用正文解析器获取,您只需这样配置:

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

这种行为不会破坏正文内容。

【讨论】:

  • 重要的是添加type参数。如果 type 被省略,则默认行为是检查类型“application/octet-stream”,如 here 所示(对于该库的大多数用户来说可能是意料之外的)。要匹配任何内容类型,请使用type: "*/*"
  • @Odysseas 说“检查”具有误导性。正确的词是“默认为”。感谢您的链接。 var type = opts.type || "application/octet-stream"
【解决方案3】:

解析我使用的所有内容类型:

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

仅通过一条路线获取原始主体:

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

在这种情况下,请注意之前的 app.use()'d 正文解析器(例如 json)首先执行 - 因此请检查 req.body 确实是 Buffer,否则恶意调用者可能会发送类似 {"length":9999999} 的内容Content-Type: application/json

【讨论】:

    猜你喜欢
    • 2016-06-21
    • 2017-08-20
    • 1970-01-01
    • 2012-07-12
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    相关资源
    最近更新 更多