Làm thế nào để lấy tham số truy vấn POST?


768

Đây là hình thức đơn giản của tôi:

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

Đây là mã Express.js /Node.js của tôi :

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

Tôi cố gắng sReq.query.emailhoặc sReq.query['email']hoặc sReq.params['email']vv Không ai trong số họ làm việc. Tất cả đều trở về undefined.

Khi tôi đổi thành một cuộc gọi Nhận, nó hoạt động, vậy .. có ý kiến ​​gì không?


33
BẢO MẬT : mọi người sử dụng bodyParser()từ câu trả lời ở đây cũng nên đọc câu trả lời của
@SeanLynch

Câu trả lời:


1251

Mọi thứ đã thay đổi một lần nữa bắt đầu từ Express 4.16.0 , giờ đây bạn có thể sử dụng express.json()express.urlencoded()giống như trong Express 3.0 .

Đây là khác nhau bắt đầu nhanh 4,0-4,15 :

$ npm install --save body-parser

và sau đó:

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

Phần còn lại giống như trong Express 3.0 :

Trước tiên, bạn cần thêm một số phần mềm trung gian để phân tích dữ liệu bài đăng của cơ thể.

Thêm một hoặc cả hai dòng mã sau:

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

Sau đó, trong trình xử lý của bạn, sử dụng req.bodyđối tượng:

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

Lưu ý rằng việc sử dụng express.bodyParser()không được khuyến khích.

app.use(express.bodyParser());

...tương đương với:

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

Mối quan tâm bảo mật tồn tại với express.multipart(), và vì vậy tốt hơn là thêm hỗ trợ cho loại mã hóa cụ thể mà bạn yêu cầu. Nếu bạn cần mã hóa nhiều phần (để hỗ trợ tải lên các tệp chẳng hạn) thì bạn nên đọc phần này .


76
Nếu câu trả lời này không hoạt động đúng, hãy đảm bảo bạn có bộ content-typetiêu đề, ví dụ:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe

6
sự khác biệt giữa việc đăng một biểu mẫu với các cặp tên / giá trị và đăng một phần thân JSON là gì? Cả hai có xuất hiện trong req.body không?
chovy

7
@chovy Vâng, họ làm. bodyParsertóm tắt dữ liệu JSON, URL được mã hóa và nhiều dữ liệu vào req.bodyđối tượng.
Kristján

7
Mã này đã cho tôi lỗi vì phần mềm trung gian không còn được gói cùng với Express; bạn sẽ phải sử dụng trình phân tích cú pháp cơ thể: github.com/senchalabs/connect#middleware
araneae

11
Để đọc json bằng Express 4, chỉ có app.use(require('body-parser').json())dòng là đủ. Và sau đó bạn có thể đọc dữ liệu json từ đối tượng cơ thể của yêu cầu của bạn, nghĩa là req.body, từ trong một định nghĩa tuyến đường.
Martin Carel

90

Quan tâm bảo mật bằng cách sử dụng express.bodyParser ()

Trong khi tất cả các câu trả lời khác hiện đang khuyên bạn sử dụng các express.bodyParser()trung gian, điều này thực sự là một wrapper xung quanh express.json(), express.urlencoded()express.multipart()middlewares ( http://expressjs.com/api.html#bodyParser ). Việc phân tích cú pháp các thân yêu cầu biểu mẫu được thực hiện bởi express.urlencoded()phần mềm trung gian và là tất cả những gì bạn cần để hiển thị dữ liệu biểu mẫu của mình trên req.bodyđối tượng.

Do mối quan tâm bảo mật với cách express.multipart()/ connect.multipart()tạo các tệp tạm thời cho tất cả các tệp đã tải lên (và không phải là rác được thu thập), hiện tại chúng tôi khuyên bạn không nên sử dụng express.bodyParser()trình bao bọc mà thay vào đó chỉ sử dụng các phần mềm trung gian bạn cần.

Lưu ý: connect.bodyParser()sẽ sớm được cập nhật để chỉ bao gồm urlencodedjsonkhi Connect 3.0 được phát hành (Express mở rộng).


Vì vậy, trong ngắn hạn, thay vì ...

app.use(express.bodyParser());

...bạn nên sử dụng

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

và nếu / khi bạn cần xử lý các biểu mẫu nhiều phần (tải lên tệp), hãy sử dụng thư viện của bên thứ ba hoặc phần mềm trung gian như nhiều phần, busboy, đẹp hơn, v.v.


Đã thêm một bình luận bên dưới câu hỏi để nhiều người nhìn thấy mối quan tâm và lời khuyên của bạn. Theo bạn, các giải pháp khác chi tiết trong bài đăng trên blog của Andrew Kelley (vẫn) có liên quan không? (chỉ yêu cầu người khác, nhu cầu của tôi hoàn toàn dành cho các công cụ nội bộ ^^)
FelipeAls

@FelipeAls - Vâng, và tôi cũng muốn tham khảo bài viết của Andrew. Bất kỳ đề xuất nào (có tính đến những nhược điểm của mỗi) đều có liên quan.
Sean Lynch

Ngoài ra, một khi Connect 3.0 được phát hành mà không bao gồm multipart()như một phần của bodyParser(), bodyParser()sẽ trở lại "an toàn", nhưng bạn sẽ cần phải bật hỗ trợ nhiều phần một cách rõ ràng bằng thư viện của bên thứ ba.
Sean Lynch

84

Lưu ý : câu trả lời này dành cho Express 2. Xem tại đây cho Express 3.

Nếu bạn đang sử dụng kết nối / express, bạn nên sử dụng phần mềm trung gian bodyParser : Nó được mô tả trong hướng dẫn 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
});

Đây là phiên bản chỉ kết nối ban đầu:

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

Cả thân và chuỗi truy vấn đều được phân tích cú pháp bằng cách sử dụng tham số xử lý kiểu Rails ( qs) thay vì thư viện cấp thấpquerystring . Để phân tích các tham số lặp lại với qs, tham số cần phải có dấu ngoặc : name[]=val1&name[]=val2. Nó cũng hỗ trợ các bản đồ lồng nhau. Ngoài việc phân tích cú pháp gửi biểu mẫu HTML, bodyParser có thể tự động phân tích các yêu cầu JSON.

Chỉnh sửa : Tôi đọc lên express.js và sửa đổi câu trả lời của tôi trở nên tự nhiên hơn với người dùng Express.


Hừm. tôi thử bodyParser (). tài liệu nói rằng tôi có thể lấy nó từ req.query () nhưng tôi không nhận được gì. Điều đó thật kỳ lạ. Tôi không có vấn đề với Get tho.
murvinlai

3
Không, req.query chỉ là thông số GET. Bạn nhận được dữ liệu POST thông qua req.body. Hàm req.params () bao gồm cả hai.
yonran

Một cú nhấp chuột đi xuống vô tình trả lời câu trả lời này mà tôi không nhận ra! Bây giờ StackOverflow sẽ không cho phép tôi thay đổi nó. Đặc biệt bực bội vì điều này rất hữu ích ... Tôi đã đưa ra một câu trả lời hay khác của bạn mà tôi rõ ràng không tìm kiếm để bù đắp cho nó. :)
HostileFork nói không tin tưởng SE

33

Điều này sẽ làm điều đó nếu bạn muốn xây dựng truy vấn được đăng mà không có phần mềm trung gian:

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

});

Điều đó sẽ gửi cái này đến trình duyệt

email=emailval&password1=pass1val&password2=pass2val

Có lẽ tốt hơn là sử dụng phần mềm trung gian mặc dù vậy bạn không phải viết đi viết lại trên mỗi tuyến.


3
thật là .... tiện dụng, cho những ai không muốn dựa vào thư viện sớm muộn gì cũng bị phản đối
Daniel

bạn có thể dễ dàng xây dựng phần mềm trung gian của riêng mình
maioman

Đây là một câu trả lời tuyệt vời nhưng tại sao lại có thêm văn bản "---------------------------- 359856253150893337905494 Bố trí nội dung: biểu mẫu-dữ liệu; tên = "FullName" Ram ---------------------------- 359856253150893337905494-- "Tôi không muốn số đó.
Nawaraj

25

Lưu ý cho người dùng Express 4:

Nếu bạn thử và đưa app.use(express.bodyParser());vào ứng dụng của mình, bạn sẽ gặp phải lỗi sau khi thử khởi động máy chủ Express:

Lỗi: Hầu hết các phần mềm trung gian (như bodyParser) không còn được đóng gói với Express và phải được cài đặt riêng. Vui lòng xem https://github.com/senchalabs/connect#middleware .

Bạn sẽ phải cài đặt gói body-parserriêng biệt từ npm , sau đó sử dụng một cái gì đó như sau (ví dụ được lấy từ trang 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();
})

Cảm ơn rất nhiều cho thông tin này. Đã kéo tóc tôi ra để đối phó với cách sử dụng bodyParser mới! Đây là một bước đột phá lớn - thực sự đánh giá cao
Tommy

1
heplp: body-Parser deprecated bodyParser: sử dụng các phần mềm trung gian json / urlencoding riêng lẻ
Mohammad Faizan khan

19

Cho một số hình thức:

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

Sử dụng nhanh

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

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

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

Đầu ra:

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

6
đã không làm việc cho tôi. cần sử dụng app.use (express.bodyParser ());
cawecoy

@cawecoy hoàn toàn đúng ở đây nhưng express.bodyParser () không hoạt động tốt đối với tôi, nó không được chấp nhận
Mohammad Faizan khan

@MohammadFaizankhan đó là một công việc thử nghiệm, tôi đã không sử dụng express nữa, bây giờ không thể giúp được. Google nó cho các chức năng tương tự như express.bodyParser (). chuc bạn may măn!
cawecoy

16

Cuối tuần:

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

Mặt trận:

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

Sau đó, để app.postyêu cầu bạn có thể nhận được giá trị bài qua req.body.{post request variable}.


biến yêu cầu bài đăng của bạn ở đây, đó có phải là id của trường đầu vào trong câu hỏi hoặc toàn bộ biểu mẫu hay không?
Eogcloud

2
express.bodyParser () không dùng nữa. cập nhật câu trả lời của bạn
Mohammad Faizan khan

15

Cập nhật cho Express 4.4.1

Middleware sau đây được xóa khỏi Express.

  • bodyParser
  • json
  • urlencoding
  • nhiều phần

Khi bạn sử dụng phần mềm trung gian trực tiếp như bạn đã làm trong express 3.0. Bạn sẽ nhận được lỗi sau:

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


Để sử dụng các phần mềm trung gian đó, bây giờ bạn cần thực hiện npm cho từng phần mềm trung gian riêng biệt.

Vì bodyParser được đánh dấu là không dùng nữa, vì vậy tôi khuyên bạn nên sử dụng cách sau đây bằng cách sử dụng json, urlencode và trình phân tích cú pháp nhiều phần như ghê gớm, kết nối nhiều phần. (Phần mềm trung gian Multipart cũng không được dùng nữa).

Cũng cần nhớ, chỉ cần xác định urlencode + json, dữ liệu biểu mẫu sẽ không được phân tích cú pháp và req.body sẽ không được xác định. Bạn cần xác định một phần mềm trung gian xử lý yêu cầu nhiều phần.

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

Tôi đoán đây là cập nhật tính năng thực sự xấu
Mohammad Faizan khan

chỉ vì lợi ích của cơ thể, tôi phải làm rất nhiều mã. hack là gì
Mohammad Faizan khan

1
Tôi đã phải thêm ".middleware ()" để yêu cầu ('json-middleware') để làm việc này.
DustinB

8

Đối với Express 4.1 trở lên

Vì hầu hết các câu trả lời đang sử dụng để Express, bodyParser, kết nối; trong đó nhiều phần không được chấp nhận Có một cách an toàn để gửi các đối tượng bài đăng dễ dàng.

Multer có thể được sử dụng để thay thế cho Connect.multipart ().

Để cài đặt gói

$ npm install multer

Tải nó trong ứng dụng của bạn:

var multer = require('multer');

Và sau đó, thêm nó vào ngăn xếp phần mềm trung gian cùng với các phần mềm phân tích cú pháp trung gian dạng khác.

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

connect.json () xử lý ứng dụng / json

connect.urlencoding () xử lý ứng dụng / x-www-form-urlencoding

multer () xử lý nhiều dữ liệu / biểu mẫu


8

Tôi đã tìm kiếm vấn đề chính xác này. Tôi đã làm theo tất cả các lời khuyên ở trên nhưng req.body vẫn trả lại một đối tượng trống {}. Trong trường hợp của tôi, đó là một cái gì đó đơn giản như html không chính xác.

Trong html của biểu mẫu của bạn, đảm bảo bạn sử dụng 'name'thuộc tính trong các thẻ đầu vào, không chỉ 'id'. Nếu không, không có gì được phân tích cú pháp.

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

Sai lầm ngốc của tôi là lợi ích của bạn.


Cùng một vấn đề ở đây. Nhưng tôi đã sử dụng thuộc tính name từ đầu. Hãy xem vấn đề là gì.
Saif Al Falah

6

Bạn sẽ không sử dụng app.use (express.bodyParser ()) . BodyParser là sự kết hợp của json + urlencoding + mulitpart. Bạn sẽ không sử dụng điều này bởi vì nhiều phần sẽ bị xóa trong kết nối 3.0.

Để giải quyết điều đó, bạn có thể làm điều này:

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

Nó rất quan trọng biết rằng app.use (app.router) nên được sử dụng sau khi json và urlencoding, nếu không nó không hoạt động!


4

Yêu cầu truyền phát làm việc cho tôi

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

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

1
Tốt hơn là làm postdata.split("&")để tải mô-đun lõi querystring = require('querystring')và sau đó phân tích cú pháp của bạn postdatavới querystring.parse(postdata);
John Slegers

4

Tôi có thể tìm thấy tất cả các tham số bằng cách sử dụng mã sau cho cả hai yêu cầu 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));
})

Bạn có phiền cập nhật câu trả lời với phiên bản express của bạn không?
lfender6445

3

Viết tại Express phiên bản 4.16

Bên trong chức năng bộ định tuyến, bạn có thể sử dụng thuộc req.bodytính để truy cập biến bài. Ví dụ: nếu đây là POSTtuyến đường của biểu mẫu của bạn, nó sẽ gửi lại những gì bạn nhập:

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

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

PS cho những người quen thuộc với PHP: Để truy cập $_GETbiến của PHP, chúng tôi sử dụng req.queryvà để truy cập $_POSTbiến của PHP, chúng tôi sử dụng req.bodytrong Node.js.


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

Thông số bài có thể được lấy như sau:

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

2
Bạn có nhận ra điều này sẽ không hiệu quả? paramđược sử dụng cho các yêu cầu GET .. không phải POST và ví dụ của bạn thiếu chi tiết, rất khó hiểu cho những người mới đến. Và trên hết request.paramlà thực sự không được chấp nhận, vì vậy ví dụ của bạn sai ở rất nhiều cấp độ.
vdegenne

0

Bạn đang sử dụng req.query.postvới phương thức sai req.query.posthoạt động với method=get, method=posthoạt động với trình phân tích cú pháp cơ thể .

Chỉ cần thử điều này bằng cách thay đổi bài đăng để có được :

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

Và trong mã nhanh, sử dụng 'app.get'


0

Sử dụng gói 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');
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.