使用 Node.js 和 Express 发布时如何访问请求正文?

Posted

技术标签:

【中文标题】使用 Node.js 和 Express 发布时如何访问请求正文?【英文标题】:How to access the request body when POSTing using Node.js and Express? 【发布时间】:2012-07-22 10:55:55 【问题描述】:

我有以下 Node.js 代码:

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();
);

现在如果我发布类似的内容:

curl -d user=Someone -H Accept:application/json --url http://localhost:5000

我按预期得到Someone。现在,如果我想获得完整的请求正文怎么办?我尝试做response.write(request.body) 但Node.js 抛出一个异常说“第一个参数必须是一个字符串或缓冲区”然后进入一个“无限循环”,异常说“Can' t 在发送后设置标题。";即使我先写了var reqBody = request.body;,然后写了response.write(reqBody),这也是正确的。

这里有什么问题?

另外,我可以在不使用express.bodyParser() 的情况下获取原始请求吗?

【问题讨论】:

response.write(reqBody) 好像有点东西;当我使用response.send(reqBody) 时,一切正常……是的,我在response.write 之后使用response.end 【参考方案1】:

您声称“尝试过”的内容正是您在使用 curl 调用时“按预期”工作的代码中编写的内容。

您遇到的错误似乎与您向我们展示的任何代码都无关。

如果您想获取原始请求,请在request 上为dataend 事件设置处理程序(当然,删除对express.bodyParser() 的任何调用)。请注意,data 事件将以块的形式发生,除非您为 data 事件设置编码,否则这些块将是缓冲区,而不是字符串。

【讨论】:

这是一个复制粘贴错误;我的意思是request.body 而不是request.body.user,我现在更正了。顺便说一句,var reqBody = request.body; 是并且仍然是正确的,当你尝试它时,你会得到我得到的错误。无论如何,你能举一个关于在request上设置处理程序的例子吗?我似乎没有在快速指南中找到它。【参考方案2】:

Express 4.0及以上:

$ npm install --save body-parser

然后在您的节点应用程序中:

const bodyParser = require('body-parser');
app.use(bodyParser);

Express 3.0及以下:

尝试在你的 cURL 调用中传递这个:

--header "Content-Type: application/json"

并确保您的数据为 JSON 格式:

"user":"someone"

此外,您可以在 node.js 代码中使用 console.dir 来查看对象内部的数据,如下例所示:

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);

这个其他问题也可能有帮助:How to receive JSON in express node.js POST request?

如果您不想使用 bodyParser,请查看其他问题:https://***.com/a/9920700/446681

【讨论】:

我尝试使用curl -d "user":"Someone" -H "Content-Type: application/json" --url http://localhost:5000,但它给了我错误“Unexpected token u”,这就是为什么我切换到我原来的帖子中提到的调用。 由于链接***.com/a/9920700/446681,我将此标记为答案 express.bodyParser() 在 Express 4.x 中已弃用。请改用npmjs.org/package/body-parser。 @TheBlueSky 你得到“Unexpected token u”的原因是因为shell消耗了你的双引号。如果您执行echo any"thing",也会发生同样的事情。您发布的数据应包含在引号内,以防止这种情况发生。 从 express 4.16.0 或更高版本可以通过这种方式在 app.use() 中使用 express.json() => app.use(express.json());【参考方案3】:

试试这个:

response.write(JSON.stringify(request.body));

这将获取bodyParser 为您创建的对象并将其转换回字符串并将其写入响应。如果您想要确切的请求正文(具有相同的空格等),您将需要dataend 侦听器附加到之前的请求并逐块构建字符串,如您在json parsing source code from connect 中所见。

【讨论】:

【参考方案4】:

从 Express 4 开始,以下代码似乎可以解决问题。 请注意,您需要使用npm 安装body-parser

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
);

【讨论】:

解析json主体需要添加下面这行app.use(bodyParser.json()) @cml.co 有什么理由需要app.use(bodyParser.urlencoded( extended: true ) 吗?我在请求中将一个相当复杂的文档作为 JSON 发布,extended: false 不起作用。只有当我将其设置为 true 时,才会正确解析请求。 只是一个注释。必须使用 app.use(bodyParser.urlencoded( extended: true ));app.use(bodyParser.json()) 在使用 NodeJS 和 Express 的 AWS Linux 服务器设置上获取 json 数据。【参考方案5】:

您使用以下代码记录发布数据:

router.post("/users",function(req,res)
    res.send(JSON.stringify(req.body, null, 4));
);

【讨论】:

给出的答案是不完整的,不包括 body-parser 模块。【参考方案6】:
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);

这将对您有所帮助。我假设你在 json 中发送正文。

【讨论】:

我总是忘记添加 bodyParser.json() 位 x_x 谢谢!【参考方案7】:

express v4.16开始不需要任何额外的模块,只需使用内置的JSON middleware:

app.use(express.json())

像这样:

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
)

注意 - body-parser,这取决于 already included 和 express。

另外别忘了发送标头Content-Type: application/json

【讨论】:

谢谢,这是 4.16+ 的最佳答案。没有其他依赖项,并且像魅力一样工作! 我能找到的不需要正文解析器的最佳/唯一解决方案【参考方案8】:

这也可以在没有body-parser 依赖的情况下实现,监听request:datarequest:end 并在请求结束时返回响应,请参阅下面的代码示例。参考: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();
    );
);

【讨论】:

【参考方案9】:

如果您懒得阅读大量帖子数据。 您可以简单地粘贴以下行 读取json。

以下是 TypeScript 的类似内容,JS 也可以这样做。

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 ));

在您的任何一个接收 POST 调用的控制器中使用如下所示

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 应该将您的 json 数据解析到您的 TS 模型中。

【讨论】:

我不确定你是在试图通过称他们为懒惰来鼓励或阻止人们使用你的答案:) 无法弄清楚如何使用 @types/express 访问我的自定义正文参数几个小时。你用那个&lt;UserModel&gt;_req.body救了我!【参考方案10】:

对于 2019 年,您无需安装 body-parser

你可以使用:

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
);

【讨论】:

【参考方案11】:

我对 JS 和 ES 完全陌生,但似乎对我有用的是:

JSON.stringify(req.body)

如果有什么问题请告诉我!

【讨论】:

正是我需要的【参考方案12】:

通过以下命令安装 Body Parser

$ npm install --save 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 ));

【讨论】:

body-parser 现已弃用【参考方案13】:

就我而言,我错过了设置标题

"Content-Type: application/json"

【讨论】:

【参考方案14】:

您不应该使用body-parser,它已被弃用。试试这个

const express = require('express')
const app = express()

app.use(express.json()) //Notice express.json middleware

app.use() 函数用于在指定的路径挂载指定的中间件函数。它主要用于为您的应用程序设置中间件。

现在要访问正文,只需执行以下操作

app.post('/', (req, res) => 
  console.log(req.body)
)

【讨论】:

【参考方案15】:

接受的答案仅适用于与 JSON 格式兼容的正文。通常,可以使用

访问正文
app.use(
  Express.raw(
    inflate: true,
    limit: '50mb',
    type: () => true, // this matches all content types
  )
);

喜欢张贴here。 req.body 具有Buffer 类型,可以转换为所需的格式。

例如通过以下方式转换成字符串:

let body = req.body.toString()

或通过以下方式转换为 JSON:

let body = req.body.toJSON();

【讨论】:

以上是关于使用 Node.js 和 Express 发布时如何访问请求正文?的主要内容,如果未能解决你的问题,请参考以下文章

使用 node.js 和 express 的 JQuery Ajax 发布请求

Express 和 node.js 中的 HTML?

开源 Node.js(和 Express)项目 [关闭]

Node.js 有条件地使用 csurf 和 express 4

Node.JS、Express 和 MongoDB :: 多个集合

Socket.io 使用 node.js,根本没有 express?