如何检索POST查询参数?


768

这是我的简单表格:

<form id="loginformA" action="userlogin" method="post">
    <div>
        <label for="email">Email: </label>
        <input type="text" id="email" name="email"></input>
    </div>
<input type="submit" value="Submit"></input>
</form>

这是我的Express.js /Node.js代码:

app.post('/userlogin', function(sReq, sRes){    
    var email = sReq.query.email.;   
}

我试过sReq.query.emailsReq.query['email']sReq.params['email'],等等。它们都不起作用。他们都回来了undefined

当我更改为Get呼叫时,它可以工作,所以..有什么想法吗?


33
安全性:使用bodyParser()此处答案的每个人还应该阅读下面的
@SeanLynch

使用主体解析器模块。以下是人体分析器的
drorw

Answers:


1250

事情已经改变了再次启动快速4.16.0,您现在可以使用express.json()express.urlencoded()就像在快车3.0

Express 4.0到4.15,这是不同的

$ npm install --save body-parser

然后:

var bodyParser = require('body-parser')
app.use( bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
  extended: true
})); 

其余的就像在Express 3.0中一样

首先,您需要添加一些中间件来解析正文的发布数据。

添加以下两行代码之一或全部:

app.use(express.json());       // to support JSON-encoded bodies
app.use(express.urlencoded()); // to support URL-encoded bodies

然后,在处理程序中,使用req.body对象:

// assuming POST: name=foo&color=red            <-- URL encoding
//
// or       POST: {"name":"foo","color":"red"}  <-- JSON encoding

app.post('/test-page', function(req, res) {
    var name = req.body.name,
        color = req.body.color;
    // ...
});

请注意,express.bodyParser()不建议使用。

app.use(express.bodyParser());

...相当于:

app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());

存在与安全性有关的问题express.multipart(),因此最好显式添加对所需特定编码类型的支持。如果您确实需要多部分编码(例如,支持上传文件),则应阅读


76
如果此答案无法正常工作,请确保已设置content-type标题,例如:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe 2012年

6
发布带有名称/值对的表单和发布JSON正文有什么区别?他们俩都出现在req.body吗?
chovy 2012年

7
@chovy是的,他们愿意。bodyParser将JSON,URL编码和多部分数据抽象到req.body对象中。
克里斯蒂安

7
这段代码给了我错误,因为中间件不再与Express捆绑在一起。您将不得不使用body-parser:github.com/senchalabs/connect#middleware
araneae 2014年

11
对于使用Express 4读取json,仅app.use(require('body-parser').json())一行就足够了。然后,您可以从请求的主体对象(即req.body从路由定义中)读取json数据。
马丁·卡雷尔

90

使用express.bodyParser()的安全问题

而所有其他的答案目前推荐使用的express.bodyParser()中间件,这其实是围绕着一个包装express.json()express.urlencoded()express.multipart()中间件(http://expressjs.com/api.html#bodyParser)。表单请求主体的解析是由express.urlencoded()中间件完成的,而这是将req.body对象上的表单数据公开所需要的全部。

由于出于安全考虑,如何express.multipart()/ connect.multipart()为所有上载的文件创建临时文件(并且不会进行垃圾回收),因此建议不要使用express.bodyParser()包装器,而应仅使用所需的中间件。

注:connect.bodyParser()即将更新到只包含urlencodedjson当连接3.0被释放(其表达延伸)。


简而言之,而不是...

app.use(express.bodyParser());

...您应该使用

app.use(express.urlencoded());
app.use(express.json());      // if needed

并且如果/当您需要处理多部分表单(文件上传)时,请使用第三方库或中间件,例如多方,busboy,dicer等。


在问题下方添加了一条评论,以便更多的人看到您的关注和建议。您认为在Andrew Kelley博客中详细介绍的其他解决方案是否仍然有意义?(只是问别人,我的需求纯粹是内部工具^^)
FelipeAls

@FelipeAls-是的,我也想参考Andrew的帖子。这些建议中的任何一个(考虑到每个建议的缺点)都是相关的。
肖恩·林奇

此外,一旦连接3.0被释放,而不包括multipart()作为的一部分bodyParser()bodyParser()成为“安全”了,但你需要使用第三方库明确启用多支持。
肖恩·林奇

84

注意:此答案适用于Express2。有关Express 3,请参见此处

如果您使用的是connect / express,则应使用bodyParser中间件Expressjs指南对此进行了说明

// example using express.js:
var express = require('express')
  , app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(req, res){
  var email = req.param('email', null);  // second parameter is default
});

这是原始的仅连接版本:

// example using just connect
var connect = require('connect');
var url = require('url');
var qs = require('qs');
var server = connect(
  connect.bodyParser(),
  connect.router(function(app) {
    app.post('/userlogin', function(req, res) {
      // the bodyParser puts the parsed request in req.body.
      var parsedUrl = qs.parse(url.parse(req.url).query);
      var email = parsedUrl.email || req.body.email;;
    });
  })
);

querystring和body均使用Rails样式的参数处理(qs而不是低级querystring进行解析。为了使用解析重复的参数qs,该参数需要使用方括号:name[]=val1&name[]=val2。它还支持嵌套地图。除了解析HTML表单提交,bodyParser还可以自动解析JSON请求。

编辑:我阅读了express.js并修改了答案,使Express用户更加自然。


嗯。。好。我尝试了bodyParser()。医生说我可以从req.query()获取它,但是我什么也没得到。那太奇怪了。我没有问题。
murvinlai

3
不,req.query只是GET参数。您可以通过req.body获得POST数据。函数req.params()包括了两者。
yonran 2011年

意外单击不小心使该答案下降,我没有注意到!现在,StackOverflow不允许我更改它。Esp。令人沮丧,因为这是有帮助的。。。我赞成您没有明确要弥补的其他好答案。:)
HostileFork说不要相信2012年

33

如果您要构建不带中间件的发布查询,则将执行此操作:

app.post("/register/",function(req,res){
    var bodyStr = '';
    req.on("data",function(chunk){
        bodyStr += chunk.toString();
    });
    req.on("end",function(){
        res.send(bodyStr);
    });

});

这会将其发送到浏览器

email=emailval&password1=pass1val&password2=pass2val

尽管使用中间件可能更好,但是您不必在每条路线中都一遍又一遍地编写。


3
太...方便了,对于那些不想依赖迟早会被弃用的图书馆的人
丹尼尔(Daniel)

您可以轻松地构建自己的中间件
maioman

这是一个很好的答案,但是为什么会有多余的文本“ ---------------------------- 359856253150893337905494 Content-Disposition:form-data;名称=“ fullName” Ram ---------------- 359856253150893337905494--“我不需要那个数字。
Nawaraj

25

Express 4用户注意事项:

如果尝试放入app.use(express.bodyParser());应用程序中,则尝试启动Express服务器时会出现以下错误:

错误:大多数中间件(如bodyParser)不再与Express捆绑在一起,必须单独安装。请参阅https://github.com/senchalabs/connect#middleware

您必须将软件包body-parsernpm分开安装,然后使用类似以下的内容(示例来自GitHub页面):

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

var app = express();

app.use(bodyParser());

app.use(function (req, res, next) {
  console.log(req.body) // populated!
  next();
})

非常感谢您提供此信息。在拉扯我的头发,试图应对使用bodyParser的新方式!这是一个巨大的突破-非常感谢
Tommy 2014年

1
heplp:不支持body-parser的bodyParser:使用单独的json / urlencoded中间件
Mohammad Faizan khan,2014年

19

给定某种形式:

<form action='/somepath' method='post'>
   <input type='text' name='name'></input>
</form>

使用快递

app.post('/somepath', function(req, res) {

    console.log(JSON.stringify(req.body));

    console.log('req.body.name', req.body['name']);
});

输出:

{"name":"x","description":"x"}
req.param.name x

6
没有为我工作。需要使用app.use(express.bodyParser());
cawecoy13年

@cawecoy在这里绝对正确,但express.bodyParser()对我来说不起作用,它已被弃用
Mohammad Faizan khan 2014年

@MohammadFaizankhan这是一个实验性工作,我不再使用express了,现在无济于事。谷歌它为express.bodyParser()类似的功能。好幸运!
cawecoy 2014年

16

后端:

import express from 'express';
import bodyParser from 'body-parser';

const app = express();
app.use(bodyParser.json()); // add a middleware (so that express can parse request.body's json)

app.post('/api/courses', (request, response) => {
  response.json(request.body);
});

前端:

fetch("/api/courses", {
  method: 'POST',
  body: JSON.stringify({ hi: 'hello' }), // convert Js object to a string
  headers: new Headers({ "Content-Type": "application/json" }) // add headers
});

15
app.use(express.bodyParser());

然后,app.post如果需要,您可以通过获取帖子值req.body.{post request variable}


您的发帖请求变量在这里,是该输入字段的ID是问题字段还是整个表单的ID?
Eogcloud 2014年

2
express.bodyParser()已弃用。更新您的答案
穆罕默德·法赞汗

15

Express 4.4.1的更新

从Express中删除了以下中间件。

  • bodyParser
  • json
  • urlencoded
  • 多部分

当您像在express 3.0中一样直接使用中间件时。您将收到以下错误:

Error: Most middleware (like urlencoded) is no longer bundled with Express and 
must be installed separately.


为了利用这些中间件,现在您需要分别为每个中间件执行npm

由于bodyParser被标记为已弃用,因此我建议通过以下方式使用json,urlencode和multipart解析器,例如强大的connect-multiparty。(不建议使用多部分中间件)。

还要记住,仅定义urlencode + json,就不会解析表单数据,并且req.body将是未定义的。您需要定义一个中间件处理多部分请求。

var urlencode = require('urlencode');
var json = require('json-middleware');
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();

app.use(json);
app.use(urlencode);
app.use('/url/that/accepts/form-data', multipartMiddleware);

我想这真的是很不好的功能更新
Mohammad Faizan khan 2014年

只是为了进行身体分析,我必须做很多代码。
骇客

1
我必须在require('json-middleware')上添加“ .middleware()”,以使其正常工作。
DustinB

8

对于Express 4.1及更高版本

由于大多数答案都用于Express,bodyParser,connect;不建议使用multipart的地方。有一种安全的方法可以轻松发送后期多部分对象。

Multer可以替代connect.multipart()。

要安装软件包

$ npm install multer

将其加载到您的应用中:

var multer = require('multer');

然后,将其与其他表单解析中间件一起添加到中间件堆栈中。

app.use(express.json());
app.use(express.urlencoded());
app.use(multer({ dest: './uploads/' }));

connect.json()处理application / json

connect.urlencoded()处理应用程序/ x-www-form-urlencoded

multer()处理多部分/表单数据


8

我正在寻找这个确切的问题。我遵循了以上所有建议,但是req.body仍返回空对象{}。就我而言,这就像html不正确一样简单。

在表单的html中,请确保您'name'在输入标签中使用属性,而不仅仅是使用'id'。否则,将不解析任何内容。

<input id='foo' type='text' value='1'/>             // req = {}
<input id='foo' type='text' name='foo' value='1' /> // req = {foo:1}

我的白痴错误是您的利益。


这里同样的问题。但是我从一开始就使用name属性。让我们看看问题出在哪里。
赛义夫·法拉

6

您不应该使用app.use(express.bodyParser())。BodyParser是json + urlencoded + mulitpart的并集。您不应该使用它,因为在connect 3.0中将删除多部分。

要解决此问题,您可以执行以下操作:

app.use(express.json());
app.use(express.urlencoded());

知道应该在json和urlencode之后使用app.use(app.router),这是非常重要的,否则它将不起作用!


4

请求流式传输对我有用

req.on('end', function() {
    var paramstring = postdata.split("&");
});

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});

1
不如做postdata.split("&")将加载核心模块querystring = require('querystring'),然后分析你postdataquerystring.parse(postdata);
John Slegers '16

4

通过对POSTGET请求使用以下代码,我可以找到所有参数。

var express = require('express');
var app = express();
const util = require('util');
app.post('/', function (req, res) {
    console.log("Got a POST request for the homepage");
    res.send(util.inspect(req.query,false,null));
})

您介意使用您的Express版本更新答案吗?
lfender6445

3

写在Express版本4.16

在router函数内部,您可以使用req.body属性访问post变量。例如,如果这是POST您的表单路线,它将发回您输入的内容:

function(req,res){
      res.send(req.body);

      //req.body.email would correspond with the HTML <input name="email"/>
}

适用于那些熟悉PHP的人的PS:为了访问$_GET我们使用的req.queryPHP $_POST变量以及我们req.body在Node.js中使用的访问PHP 变量。


1
var express        =         require("express");
var bodyParser     =         require("body-parser");
var app            =         express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.get('/',function(req,res){
  res.sendfile("index.html");
});
app.post('/login',function(req,res){
  var user_name=req.body.user;
  var password=req.body.password;
  console.log("User name = "+user_name+", password is "+password);
  res.end("yes");
});
app.listen(3000,function(){
  console.log("Started on PORT 3000");
})

1

可以按以下方式检索发布参数:

app.post('/api/v1/test',Testfunction);
http.createServer(app).listen(port, function(){
    console.log("Express server listening on port " + port)
});

function Testfunction(request,response,next) {
   console.log(request.param("val1"));
   response.send('HI');
}

1
您知道这行不通吗?param用于GET请求。不是POST,您的示例缺少详细信息,对于新手来说非常令人困惑。最重要的request.param是,实际上已经过时了,因此您的示例在很多层面上都是错误的。
vdegenne

0

您正在使用req.query.post与错误的方法req.query.post作品有method=getmethod=post用作品身体解析器

只需通过改变试试这个岗位,以获得

<form id="loginformA" action="userlogin" method="get">
<div>
    <label for="email">Email: </label>
    <input type="text" id="email" name="email"></input>
</div>
<input type="submit" value="Submit"></input>  
</form>

在快速代码中使用“ app.get”


0

使用express-fileupload软件包:

var app = require('express')();
var http = require('http').Server(app);
const fileUpload = require('express-fileupload')

app.use(fileUpload());

app.post('/', function(req, res) {
  var email = req.body.email;
  res.send('<h1>Email :</h1> '+email);
});

http.listen(3000, function(){
  console.log('Running Port:3000');
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.