无法使用 Express.js 从请求中获取 POST 正文

Posted

技术标签:

【中文标题】无法使用 Express.js 从请求中获取 POST 正文【英文标题】:Can't get POST body from request using Express.js 【发布时间】:2013-12-21 06:36:49 【问题描述】:

我正在使用 NodeJS 和 Express(以及更多的东西,如 mongo、套接字等)开发 API,但我相信我坚持一个非常简单的步骤。我只是想从 POST req 对象中获取信息,但在尝试访问 req.body 时出现错误

这是我所拥有的:

var express     = require('express'),
    http        = require('http'),
    path        = require('path'),
    fs          = require('fs'),
    io          = require('socket.io');
    dynroute    = require('dynroute');

var app = express();
app.set('port', process.env.PORT || 3999);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(app.router);
app.use(express.bodyParser());

app.post('/user', function(req, res) 

    console.log(JSON.stringify(req.body));
    res.send(req.body.self);
);

http.createServer(app).listen(app.get('port'), function ()

    console.log('App Server is now running at:' + app.get('port'));     
);

console.log(JSON.stringify(req.body)); 我得到undefinedres.send(req.body.self); 我得到TypeError: Cannot read property 'self' of undefined

我一直在寻找这种类型的错误,通常问题是人们不包含 app.use(express.bodyParser()); 中间件,所以我也尝试使用 app.use(express.urlencoded());app.use(express.json());,但也没有用。

如果我执行console.log(req),我可以看到整个对象,但看不到body 或我在从客户端执行 POST 请求时传递的任何内容(我将其传递为JSON)。

**我知道我可以使用 restifysails.js 在 Node 中构建 API,但我想自己做所有事情,以便从经验中学习。*

谢谢

编辑: 我不得不将bodyparser 中间件放在app.router 中间件之前,这样就解决了!

【问题讨论】:

我建议发布有关您如何发出发布请求的信息。如果 req 对象没有接收到“body”,那么我的第一个想法是 post 请求没有成功。 我正在使用一个名为 Advanced Rest Client 的 Chrome 应用程序,我只是向我的 URL 发出一个 POST 请求,将 ['user':'kevinblanco'] 作为内容,并将 application/json 作为内容类型标头。跨度> 我希望 express、node 有一个版本号,无论这个问题(及其答案)中指出什么。我认为它现在已经过时了,因为今天遇到了这样的问题,但只有当远程服务器返回状态代码 4xx 时。表达 4.13.1。身体解析器 1.13.2。接受的答案也无济于事。 【参考方案1】:

bodyParser 中间件移到router 中间件上方!

var app = express();
app.set('port', process.env.PORT || 3999);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(app.router);

【讨论】:

很高兴帮助你@kevinblanco - 如果这解决了你的问题,请接受答案:)) 非常感谢 renatoargh...在我得到你的答案之前我已经发疯了 并且不要忘记在标题中使用Content-Type: application/json 调用您的服务器,否则req.body 中将没有数据。 我在今天退出前两分钟遇到了这个解决方案。谢谢!【参考方案2】:

对我来说,@kevinblanco 的注释是“我必须将 bodyparser 中间件放在 app.router 中间件之前,这样可以解决它!”为我做的。把它放在一个单独的答案中,因为它被埋在底部。

您的代码需要如下所示:

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// My routing here

【讨论】:

【参考方案3】:

BodyParser 不再与 Express 捆绑

npm install body-parser
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded( extended: false ));

【讨论】:

解析json主体,添加以下行:app.use(bodyParser.json()) 截至 16 年 1 月,bug 仍然存在。我正在使用 Express 4.13.1。身体解析器 1.13.2。仅当状态码为 4xx 时,我无法获取正文:错误页面的呈现失败并且节点服务器爆炸。当状态码为 2xx 时,没问题。尝试了此页面中提出的所有解决方案。这很奇怪! 我将它与 express 4.16.4 版本一起使用这对我不起作用 app.use(bodyParser.urlencoded(extended: true)) app.use(bodyParser.json()) app .post('/user_create',(req,res)=> console.log("正在尝试创建用户"); const firstName = req.body.create_first_name const lastName = req.body.create_last_name console.log("名字是 "+firstName+" "+lastName); res.end() )【参考方案4】:

Content-Type = "application/json" 应该是Request Headers 之一

【讨论】:

我不知道您为什么投了反对票。Express 4.0 附带了您评论上方列出的所有修复程序,因此它们毫无用处。在使用 REST 测试扩展时,您必须分配一个 Content-Type。很棒的东西:) 对我来说就是这种情况,并且在 Google Chrome 中使用本机 fetch API 不会将 content-type 标头默认为 application/json,因此服务器端没有任何正文解析作为传入请求发生必须被解释为文本。【参考方案5】:

在 Golang 中,您可以在向 nodejs express 路由器发送 POST http 客户端请求之前将 Content-Type 设置为 application/json:

//Golang
import (    
    "bytes"
    "encoding/json"
    "errors"    
    "net/http"      
)

//method := "POST"
//url := "http://ip:port/api/router"

func request(method string, url string, data interface, pHeader map[string]string) 
    pBody, err := json.Marshal(data)
    if err != nil 
        return []byte, err
    
    request, err = http.NewRequest(method, url, bytes.NewBuffer(pBody))
    if(err!=nil )
        return []byte, err
    
    request.Header.Set("Content-Type", "application/json")

    //add header params if any
    for key, head := range pHeader 
        request.Header.Add(key, head)
    

    client := &http.Client
    resp, err := client.Do(request)
    if err != nil 
       return []byte, err
    
    defer resp.Body.Close() 


//NODEJS

//app.js
var express = require('express');
...

var app = express();
app.use(express.json());


var router= require('path/to/router.js');
//use the router
app.use('/api', router);
...

//router.js    
router.post('/router', function (req, res, next) 
    //log request body to view its values of incoming request
    console.log('req.body', req.body)
)

【讨论】:

【参考方案6】:

Express 有一个内置的方法来识别来自客户端的 POST 请求中的 JSON 对象。您可以在 index.js 文件中使用它,而不是使用 body-parser:

app.use(express.json());

【讨论】:

【参考方案7】:

上面列出的大多数答案都是正确的,但目前 [28-July-2020] 最合适的答案是使用内置的 express 即:

app.use(express.json());

这将作为一个中间件在你的请求中接受传入的 JSON 对象

【讨论】:

【参考方案8】:

在我的情况下,我必须添加这两行来阅读帖子请求正文

app.use(express.json());

// add this middleware to read post request body
app.use(express.text());

【讨论】:

以上是关于无法使用 Express.js 从请求中获取 POST 正文的主要内容,如果未能解决你的问题,请参考以下文章

无法在express.js中获取所请求的API

在express.js中间件请求中获取“#”之后的url

无法将多部分表单数据从 React 正确发送到 Express Js

无法使用邮递员从 express.js 服务器获得响应

在前端使用 fetch 从 express.js 服务器获取响应

每次在 Node.js (Express.js) 中发出 API 请求之前,如何简化 Fetching Auth token?