如何在Express中访问POST表单字段

这是我的简单形式:

<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

当我改为获取呼叫时,它起作用了,所以…有什么想法吗?

900091 次浏览

说明:此答案适用于Express 2。Express 3见这里

如果您使用的是Connect/Express,则应该使用Body Parser中间件:它在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 connectvar 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;;});}));

查询字符串和主体都是使用Rails样式的参数处理(#0)而不是低级#1库解析的。为了用qs解析重复的参数,参数需要有括号:name[]=val1&name[]=val2。它还支持嵌套映射。除了解析超文本标记语言表单提交外,Body Parser还可以自动解析JSON请求。

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

给定某种形式:

<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
app.use(express.bodyParser());

然后对于app.post请求,您可以通过req.body.{post request variable}获取帖子值。

事情有改变再次开始Express 4.16.0,你现在可以使用express.json()express.urlencoded()就像在Express 3.0

这是从快递4.0到4.15开始的不同

$ npm install --save body-parser

然后:

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

剩下的就像Express 3.0

首先,您需要添加一些中间件来解析主体的post数据。

添加以下一行或两行代码:

app.use(express.json());       // to support JSON-encoded bodiesapp.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()存在安全问题,因此最好显式添加对您需要的特定编码类型的支持。如果您确实需要多部分编码(例如支持上传文件),那么您应该读这个

使用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,当Connect 3.0发布时(Express扩展)。


所以简而言之,不是…

app.use(express.bodyParser());

…你应该用

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

如果/当您需要处理多部分表单(文件上传)时,请使用第三方库或中间件,例如多方、服务员、切割机等。

您不应该使用app.use(express.bodyParser())。BodyParser是json+urlencoded+mulitpart的联合。您不应该使用它,因为multipart将在Connect 3.0中被删除。

要解决这个问题,你可以这样做:

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

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

Express 4用户注意事项:

如果您尝试将app.use(express.bodyParser());放入您的应用程序,当您尝试启动Express服务器时,您将收到以下错误:

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

您必须单独安装包body-parser从npm,然后使用以下内容(取自的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();})

Express 4.4.1更新

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

  • 身体解析器
  • json
  • urlencoded
  • 多部分

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

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


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

由于Body Parser被标记为已弃用,因此我建议使用json、urlencode和multipart解析器,例如强大的连接多方。(Multipart中间件也已弃用)。

还要记住,只定义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);

如果您想在没有中间件的情况下构建发布的查询,这将执行此操作:

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

使用中间件可能更好,这样你就不必在每个路由中一遍又一遍地写这个。

请求流对我有用

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

Express 4.1及以上

由于大多数答案都使用Express、Body Parser、Connect;其中不建议使用multipart。有一种安全的方法可以轻松发送post 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()处理应用程序/json

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

multer()处理multipart/form-data

后端:

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 stringheaders: new Headers({ "Content-Type": "application/json" }) // add headers});

我可以通过使用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));})

我正在寻找这个确切的问题。我遵循了上面的所有建议,但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}

我的愚蠢的错误是你的好处。

Post参数可以通过以下方式检索:

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

使用文件快速上传包:

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');});
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");})

您使用req.query.post与错误的方法req.query.postmethod=get一起工作,method=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”

使用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的人:为了访问PHP的$_GET变量,我们使用req.query,访问PHP的$_POST变量,我们在Node.js.中使用req.body

当您使用超文本标记语言形式的POST方法时,您需要从服务器端的req.body捕获数据,即Node.js.并添加

var bodyParser = require('body-parser')app.use( bodyParser.json() );app.use(bodyParser.urlencoded({extended: false}));

在超文本标记语言中使用方法='GET',并通过服务器端的req.query捕获数据,即Node.js

官方 doc版本4

const express = require('express')const app = express()app.use(express.json());app.use(express.urlencoded({ extended: true }))
app.post('/push/send', (request, response) => {console.log(request.body)})

更新

Express version 4.16+开始,他们自己的身体解析器实现现在包含在默认的Express包中,因此您无需下载另一个依赖项。

您可能在代码中添加了如下所示的行:

app.use(bodyparser.json()); //utilizes the body-parser package

如果您使用的是Express 4.16+,您现在可以将该行替换为:

app.use(express.json()); //Used to parse JSON bodies

这不应该在应用程序中引入任何破坏性的更改,因为express.json()中的代码基于bodyparser.json()。

如果您的环境中还有以下代码:

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

您可以将其替换为:

app.use(express.urlencoded()); //Parse URL-encoded bodies

最后需要注意的是:仍然有一些非常具体的情况,其中body-parser可能仍然是必要的,但在大多数情况下,Express'实现身体解析器是大多数用例所需要的。

(有关更多详细信息,请参阅Expresjs/身体解析器的文档)。

Express v4.17.0

app.use(express.urlencoded( {extended: true} ))
app.post('/userlogin', (req, res) => {
console.log(req.body) // object
var email = req.body.email;
}

express.urlencoded

演示表

相关答案

其他答案讨论了在服务器端使用的中间件。我的回答试图为开发人员提供一个简单的剧本来自己调试问题。


在这个问题中,情况是:

  • 你在客户端有一个形式
  • 数据是通过单击提交按钮发送的,并且您不使用JavaScript发送请求(所以没有fetchaxiosxhr……但我们可以稍后扩展这些情况的解决方案)
  • 您在服务器端使用Express
  • 您的Express代码中的无法访问数据req.bodyundefined

您可以通过一些操作自行找到解决方案:

  1. 打开网络选项卡并搜索您的请求。
  2. 检查请求头#0。在这种情况下(表单提交),如果您发送文件(表单标记中有enctype="multipart/form-data"),标题可能是application/x-www-form-urlencodedmultipart/form-data
  3. 现在检查您的Express代码,如果您使用适当的中间件来解析传入的请求。
  • 如果您的Content-Type是application/x-www-form-urlencoded,那么您的代码中应该有app.use(express.urlencoded({extended: true}))

  • 如果您的Content-Type是multipart/form-data:因为Express没有内置的中间件来解析这种请求,您应该为此使用另一个库。multer是一个很好的。

  1. 如果您已经完成了上述所有步骤,现在您可以访问req.body:)中的数据。如果您对语法有问题,您应该检查快递文档页。语法可能会更改,因为这个问题是很久以前发布的。

现在,我们可以将这个简单的剧本扩展到其他涉及JavaScript代码的情况。关键是检查请求Content-Type。如果你看到application/json,那么你应该在代码中使用app.use(express.json())

总之,找到您的请求Content-Type,然后使用适当的中间件对其进行解析