【问题标题】:How to access POST form fields如何访问 POST 表单字段
【发布时间】:2021-10-18 02:13:37
【问题描述】:

这是我的简单表格:

<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.email 或sReq.query['email'] 或sReq.params['email'] 等。它们都不起作用。他们都返回undefined。

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

【问题讨论】:

标签: javascript node.js post express


【解决方案1】:

changed 再次启动 Express 4.16.0,您现在可以像在 Express 3.0 中一样使用 express.json() 和 express.urlencoded()。

这是different 开始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 中的:

首先你需要添加一些中间件来解析body的post数据。

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

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() 存在安全问题,因此最好明确添加对您需要的特定编码类型的支持。如果您确实需要多部分编码(例如支持上传文件),那么您应该read this。

【讨论】:

  • 如果此答案不正确,请确保您设置了 content-type 标头,例如:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
  • 发布带有名称/值对的表单和发布 JSON 正文有什么区别?他们都出现在 req.body 中吗?
  • @chovy 是的,他们有。 bodyParser 将 JSON、URL 编码和多部分数据抽象到 req.body 对象中。
  • 这段代码给了我错误,因为中间件不再与 Express 捆绑在一起;您必须使用正文解析器:github.com/senchalabs/connect#middleware
  • 对于使用 Express 4 读取 json,只需 app.use(require('body-parser').json()) 行就足够了。然后您可以从路由定义中读取请求的主体对象(即req.body)中的 json 数据。
【解决方案2】:

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

虽然目前所有其他答案都建议使用 express.bodyParser() 中间件,但这实际上是 express.json()、express.urlencoded() 和 express.multipart() 中间件 (http://expressjs.com/api.html#bodyParser) 的包装。表单请求正文的解析由 express.urlencoded() 中间件完成,您只需在 req.body 对象上公开表单数据即可。

由于 security concern 与 express.multipart()/connect.multipart() 如何为所有上传的文件创建临时文件(并且不是垃圾收集),现在 recommended 不使用express.bodyParser() 包装器,但只使用您需要的中间件。

注意:connect.bodyParser() 将很快更新为仅在 Connect 3.0 发布(Express 扩展)时包含 urlencoded 和 json。


所以简而言之,而不是...

app.use(express.bodyParser());

...你应该使用

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

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

【讨论】:

  • 在问题下方添加评论,让更多​​人看到您的疑虑和建议。您认为Andrew Kelley blog post(仍然)中详述的其他解决方案是否相关? (只是求别人,我的需求纯属内部工具^^)
  • @FelipeAls - 是的,我也打算参考 Andrew 的帖子。这些建议中的任何一个(考虑到每个建议的缺点)都是相关的。
  • 此外,一旦 Connect 3.0 发布,但不包含 multipart() 作为 bodyParser() 的一部分,bodyParser() 将再次变得“安全”,但您需要使用第三方库显式启用多部分支持.
【解决方案3】:

注意:此答案适用于 Express 2。请参阅 here for Express 3。

如果您使用 connect/express,则应使用 bodyParser middleware:在 Expressjs guide 中进行了描述。

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

查询字符串和正文都使用Rails-style parameter handling (qs) 而不是low-level querystring library 进行解析。为了解析带有qs的重复参数,参数需要有括号:name[]=val1&amp;name[]=val2。它还支持嵌套地图。除了解析 HTML 表单提交,bodyParser 还可以自动解析 JSON 请求。

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

【讨论】:

  • 嗯好的。我试试bodyParser()。医生说我可以从 req.query() 得到它,但我什么也没得到。这很奇怪。 Get tho 我没有问题。
  • 不,req.query 只是 GET 参数。您通过 req.body 获取 POST 数据。函数 req.params() 包括它们两者。
  • 在我没有注意到的情况下,一个杂散的点击意外地否决了这个答案!现在 StackOverflow 不会让我改变它。特别是。令人沮丧,因为这很有帮助......我赞成你的另一个好答案,我并没有明确地寻找来弥补它。 :)
【解决方案4】:

如果您想在没有中间件的情况下构建发布的查询,这将做到这一点:

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

不过使用中间件可能会更好,这样您就不必在每条路由中一遍又一遍地编写它。

【讨论】:

  • sooo.... 很方便,对于那些不想依赖迟早会被弃用的库的人来说
  • 您可以轻松构建自己的中间件
  • 这是一个很好的答案,但为什么会有额外的文字“----------------------------359856253150893337905494 内容-处置:form-data; name="fullName" Ram ----------------------------359856253150893337905494--" 我不想要那个号码。
【解决方案5】:

Express 4 用户注意事项:

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

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

您必须单独安装包body-parser from npm,然后使用类似以下的内容(示例取自the GitHub page):

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 的新方法!这是一个重大突破 - 非常感谢
  • heplp:body-parser 已弃用 bodyParser:使用单独的 json/urlencoded 中间件
【解决方案6】:

给定某种形式:

<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());
  • @cawecoy 在这里完全一样,但 express.bodyParser() 对我来说效果不佳,它已弃用
  • @MohammadFaizankhan 这是一个实验性的工作,我不再使用快递,现在无能为力。谷歌它有类似的功能 express.bodyParser()。祝你好运!
【解决方案7】:

后端:

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

【讨论】:

  • 啊,在 JavaScript 中总是默认使用 JSON。
【解决方案8】:
app.use(express.bodyParser());

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

【讨论】:

  • 你这里的post请求变量,是输入字段的id还是整​​个表单还是什么?
  • express.bodyParser() 已弃用。更新你的答案
【解决方案9】:

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

【讨论】:

  • 我想这是一个非常糟糕的功能更新
  • 只是为了身体解析我必须做很多代码。黑客是什么
  • 我必须将 ".middleware()" 添加到 require('json-middleware') 才能使其正常工作。
【解决方案10】:

我正在寻找这个确切的问题。我遵循了上面的所有建议,但 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 属性。让我们看看问题是什么。
【解决方案11】:

对于 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() 处理应用程序/json

connect.urlencoded() 处理 application/x-www-form-urlencoded

multer() 处理 multipart/form-data

【讨论】:

    【解决方案12】:

    更新

    从 Express version 4.16+ 开始,他们自己的 body-parser 实现现在包含在默认的 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' 的 body-parser 实现是大多数用例所需要的。

    (有关详细信息,请参阅expressjs/bodyparser 的文档)。

    【讨论】:

      【解决方案13】:

      你不应该使用 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之后使用很重要,否则不起作用!

      【讨论】:

        【解决方案14】:

        请求流式传输对我有用

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

        【讨论】:

        • 比postdata.split("&amp;") 更好的是加载核心模块querystring = require('querystring'),然后用querystring.parse(postdata) 解析你的postdata;
        【解决方案15】:

        编写于 Express 4.16 版

        在路由器函数中,您可以使用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。

        【讨论】:

          【解决方案16】:

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

          Demo Form

          Another Answer Related

          【讨论】:

          • 设置extended为true的目的是什么?这是什么意思?
          【解决方案17】:

          我可以通过对 POST 和 GET 请求使用以下代码来找到所有参数。

          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 版本更新答案吗?
          【解决方案18】:
          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");
          })
          

          【讨论】:

            【解决方案19】:

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

            【讨论】:

            • 你知道这行不通吗? param 用于 GET 请求.. 不是 POST 并且您的示例缺少详细信息,对于新手来说非常混乱。最重要的是,request.param 实际上已被弃用,因此您的示例在很多层面上都是错误的。
            【解决方案20】:

            您正在使用 req.query.post 错误的方法 req.query.post 适用于 method=get,method=post 适用于 body-parser。

            只需将 post 更改为 get 即可:

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

            并且在 express 代码中使用 'app.get'

            【讨论】:

            • 使用POST而不是GET的原因有很多——安全性和数据大小都在前面——所以这不是一个合适的方法。
            【解决方案21】:

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

            【讨论】:

              【解决方案22】:

              来自official 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)
              })
              

              【讨论】:

                【解决方案23】:

                当您在 HTML 表单中使用 POST 方法时,您需要从服务器端(即 Node.js)的 req.body 中捕获数据。 并添加

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

                或

                在 HTML 中使用 method='GET' 并在服务器端(即 Node.js)通过 req.query 捕获数据

                【讨论】:

                  猜你喜欢
                  • 2018-11-05
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-11-03
                  • 2016-03-19
                  • 1970-01-01
                  相关资源
                  最近更新 更多