Req.body không xác định


291

Tôi có cấu hình này của máy chủ Express

app.use(app.router); 
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

Nhưng khi tôi yêu cầu req.body.somethingtrong các tuyến đường của mình, tôi gặp một số lỗi chỉ ra điều đó body is undefined. Dưới đây là một ví dụ về tuyến đường sử dụng req.body:

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

Tôi đọc rằng vấn đề này là do thiếu app.use(express.bodyParser());nhưng như bạn có thể thấy tôi gọi nó trước các tuyến đường.

Có manh mối nào không?

Câu trả lời:


296

Bạn phải đảm bảo rằng bạn xác định tất cả các cấu hình TRƯỚC KHI xác định tuyến đường. Nếu bạn làm như vậy, bạn có thể tiếp tục sử dụng express.bodyParser().

Một ví dụ như sau:

var express = require('express'),
    app     = express(),
    port    = parseInt(process.env.PORT, 10) || 8080;

app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});

app.listen(port);

app.post("/someRoute", function(req, res) {
  console.log(req.body);
  res.send({ status: 'SUCCESS' });
});

9
Điều này làm việc cho tôi. Lưu ý: Thật không may, một số hướng dẫn ngoài kia có những người (như tôi) đặt các tuyến đường trước app.configure (). Trong trường hợp của tôi, đây là dạng app.get / post, v.v. và yêu cầu () bao gồm cả chúng.
uốn cong

1
Cảm ơn rất nhiều, tôi đã khắc phục sự cố này cả ngày.
jfplataroti

11
kể từ express 4, app.use (app.router) bị xóa. vui lòng xem tài liệu github.com/visionmedia/express/wiki/New-features-in-4.x
Jonathan Ong

15
kể từ Express 4, 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. Bạn có thể tìm thêm thông tin ở đây: github.com/senchalabs/connect#middleware .
andrea.rinaldi

2
Cảm ơn. Câu trả lời này đã hơn 2 năm tuổi và vẫn tiếp tục giúp đỡ những người gặp rắc rối :)
Lorenzo Marcon

275

Các phiên bản mới nhất của Express (4.x) đã giải quyết phần mềm trung gian từ khung cốt lõi. Nếu bạn cần trình phân tích cú pháp cơ thể, bạn cần cài đặt riêng

npm install body-parser --save

và sau đó làm điều này trong mã của bạn

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

2
Gần đây tôi đã cập nhật để thể hiện 4.x. Ban đầu khi tôi đang cố gắng đăng nhập req.body Nó đang hiển thị cho tôi không xác định. Khi tôi đã cài đặt và sử dụng trình phân tích cú pháp cơ thể, nó mang lại cho tôi các giá trị req.body mong đợi. :)
Alok Adhao 4/10/2015

Tôi thấy điều này hữu ích khi cố gắng tìm ra lý do tại sao các yêu cầu POST của tôi không hoạt động với json-server.
freethebees

Đã lưu ngày của tôi, đặc biệt là phần 'app.use (bodyParser.json ())'. Cảm ơn nhé người anh em ! : D
neaGaze

Đây phải là câu trả lời được chấp nhận vì nó hoàn toàn hoạt động cho Express 4! Cảm ơn ngài!
Kết hợp

2
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) cứu tôi !!
Pramesh Bajracharya

70

Không. Bạn cần sử dụng app.use(express.bodyParser())trước app.use(app.router). Trong thực tế, app.use(app.router)nên là điều cuối cùng bạn gọi.


Ngay cả việc di chuyển app.use(app.router)theo các .usecuộc gọi cũng không giải quyết được vấn đề :(.
Masiar

Ok sau một chút vật lộn tôi đã giải quyết nó bằng cách sử dụng app.use(require('connect').bodyParser());thay vì app.use(express.bodyParser());.
Masiar

có, câu trả lời là đúng ngay cả khi sử dụng var router=express.Router();
Istiaque Ahmed

1
Phụ lục nhẹ, bạn vẫn nên gọi phần mềm trung gian xử lý lỗi sau app.router
craft

BÌNH LUẬN NÀY
Ke Ke

40

Trước tiên, hãy đảm bảo, bạn đã cài đặt mô-đun npm có tên 'body-Parser' bằng cách gọi:

npm install body-parser --save

Sau đó, đảm bảo bạn đã bao gồm các dòng sau trước khi gọi các tuyến

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

app.use(bodyParser.json());

Nếu nó đang sử dụng express.json, thì tại sao phải nhập trình phân tích cú pháp cơ thể?
SanSolo

38

Express 4, có trình phân tích cú pháp cơ thể tích hợp. Không cần phải cài đặt trình phân tích cơ thể riêng biệt. Vì vậy, dưới đây sẽ làm việc:

export const app = express();
app.use(express.json());

37

Tiêu đề Kiểu nội dung trong tiêu đề yêu cầu thực sự quan trọng, đặc biệt là khi bạn đăng dữ liệu từ curl hoặc bất kỳ công cụ nào khác.

Hãy chắc chắn rằng bạn đang sử dụng một số thứ như application / x-www-form-urlencoding, application / json hoặc những thứ khác, nó phụ thuộc vào dữ liệu bài đăng của bạn. Để trống trường này sẽ gây nhầm lẫn Express.


12
+1 Đây là vấn đề đối với tôi. Tôi đã sử dụng Postman cho Chrome để kiểm tra api JSON được tích hợp trong REST, nhưng đối tượng mà Express nhận được luôn trống. Hóa ra Postman theo mặc định không tự động thêm tiêu đề 'Content-Type: application / json' ngay cả khi bạn chọn raw> json.
Jordan

@Jordan +1 Cảm ơn bạn đã chỉ ra điều này. Quả thực tôi chỉ kiểm tra các tiêu đề của mình và tôi thấy nó vẫn được đặt thành 'văn bản / đơn giản' mặc dù tôi đã chọn 'json'.
Kỹ sư

Ugh ... 7 năm sau và đây vẫn là thứ khiến tôi vấp ngã ...
Shaun314

33

Như đã được đăng dưới một bình luận, tôi đã giải quyết nó bằng cách sử dụng

app.use(require('connect').bodyParser());

thay vì

app.use(express.bodyParser());

Tôi vẫn không biết tại sao đơn giản express.bodyParser()không hoạt động ...


1
@Masiar Điều này không làm việc cho tôi. Tôi đang sử dụng expressjs 4 và tôi gặp lỗi như thế này. Lỗi: Không thể tìm thấy mô-đun 'kết nối'
Jeyarathnem Jeyachanthuru

1
@JeyTheva của tôi là một giải pháp khá cũ, do đó mọi thứ có thể đã thay đổi theo thời gian. Tôi đề nghị bạn thử cài đặt connectmô-đun qua npm install connectvà thử lại. Đây là điều duy nhất tôi có thể nghĩ đến bằng cách đọc kết quả lỗi của bạn.
Masiar

4
Đây là tài liệu mới nhất để giải quyết vấn đề này: npmjs.com/package/body-parser Đối với những người khác gặp phải vấn đề này "post express 4", điều làm việc cho tôi là đặt Content-Typetiêu đề application/json.
Cấp Eagon

3
Đây là tài liệu mới nhất để giải quyết vấn đề này: npmjs.com/package/body-parser Sau khi cài đặt trình phân tích cú pháp cơ thể, nó vẫn không hoạt động. Những gì đã làm là đặt Content-Typetiêu đề application/jsonkhi tôi đang thực hiện yêu cầu của tôi.
Cấp Eagon

1
application/jsonvs text/jsontrong yêu cầu hoạt động, như được đề xuất bởi @GrantEagon.
strider

21
// Require body-parser (to receive post data from clients)

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

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

// parse application/json

app.use(bodyParser.json())

20

Thêm vào của bạn app.js

trước cuộc gọi của Router

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

2
bạn đã cứu người đàn ông của tôi! Chìa khóa được thêm dòng trước bộ định tuyến cuộc gọi
ubaldisney

Điều này đã cứu tôi. Thankss :)
Farrukh Faizy

12

Có vẻ như trình phân tích cú pháp cơ thể không còn được vận chuyển với express. Chúng tôi có thể phải cài đặt nó một cách riêng biệt.

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!

Tham khảo trang git https://github.com/expressjs/body-parser để biết thêm thông tin và ví dụ.


1
Đây có vẻ là định dạng Express 4.x mới và hoạt động với tôi. Express.bodyParser () được đề cập trong các câu trả lời khác không hoạt động trong 4.x.
DustinB

10

Trong trường hợp bất cứ ai gặp phải vấn đề tương tự tôi đang gặp phải; Tôi đang sử dụng một tiền tố url như

http://example.com/api/

được thiết lập với bộ định tuyến

app.use('/api', router); 

và sau đó tôi đã có những điều sau đây

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

Điều đã khắc phục vấn đề của tôi là đặt cấu hình bodyparser ở trên app.use('/api', router);

Sau cùng

// setup bodyparser
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

//this is a fix for the prefix of example.com/api/ so we dont need to code the prefix in every route
    app.use('/api', router); 

9

express.bodyParser () cần được cho biết loại nội dung đó là phân tích cú pháp. Do đó, bạn cần đảm bảo rằng khi bạn thực hiện một yêu cầu POST, bạn sẽ bao gồm tiêu đề "Kiểu nội dung". Mặt khác, bodyParser có thể không biết phải làm gì với phần thân của yêu cầu POST của bạn.

Nếu bạn đang sử dụng curl để thực thi một yêu cầu POST có chứa một số đối tượng JSON trong phần thân, nó sẽ trông giống như thế này:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute

Nếu sử dụng phương thức khác, chỉ cần đảm bảo đặt trường tiêu đề đó bằng bất kỳ quy ước nào là phù hợp.


8

Sử dụng app.use (bodyparser.json ()); trước khi định tuyến. //. app.use ("/ api", tuyến đường);



7

Hầu hết thời gian req.body không được xác định do thiếu trình phân tích cú pháp JSON

const express = require('express');
app.use(express.json());

có thể bị thiếu cho trình phân tích cú pháp cơ thể

const bodyParser  = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

và đôi khi nó không được xác định do nguồn gốc cros vì vậy hãy thêm chúng

const cors = require('cors');
app.use(cors())

5

Điều này xảy ra với tôi ngày hôm nay. Không có giải pháp nào ở trên làm việc cho tôi. Nhưng một chút googling đã giúp tôi giải quyết vấn đề này. Tôi đang mã hóa cho máy chủ của bên thứ 3 wechat.

Mọi thứ trở nên phức tạp hơn một chút khi ứng dụng node.js của bạn yêu cầu đọc dữ liệu POST, chẳng hạn như yêu cầu từ máy khách REST. Trong trường hợp này, thuộc tính "có thể đọc" của yêu cầu sẽ được đặt thành đúng và dữ liệu POST phải được đọc theo từng khối để thu thập tất cả nội dung.

http://www.primaryobjects.com/CMS/Article144


bài đăng đề cập đến việc gửi biểu mẫu HTML khác với yêu cầu REST Client. không phải cả hai yêu cầu http? Vì vậy, POST là trường hợp duy nhất yêu cầu phát trực tuyến?
j10

5

Lãng phí rất nhiều thời gian:

Tùy thuộc vào Content-Type tại của bạn khách hàng yêu cầu
các máy chủ nên có khác nhau, một trong những dưới đây app.use ():

app.use(bodyParser.text({ type: 'text/html' }))
app.use(bodyParser.text({ type: 'text/xml' }))
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
app.use(bodyParser.json({ type: 'application/*+json' }))

Nguồn: https://www.npmjs.com/package/body-parser#bodyparsertextoptions

Thí dụ:

Đối với tôi, về phía Khách hàng, tôi có tiêu đề bên dưới:

Content-Type: "text/xml"

Vì vậy, về phía máy chủ, tôi đã sử dụng:

app.use(bodyParser.text({type: 'text/xml'}));

Sau đó, req.body làm việc tốt.


5

trong Express 4, nó thực sự đơn giản

const app = express()
const p = process.env.PORT || 8082

app.use(express.json()) 

4

Để làm việc, bạn cần app.use (app.router) sau app.use (express.bodyParser ()) , như thế:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);

1
Nhận xét và đoạn mã của bạn trái ngược nhau. Trước tiên, bạn nói rằng bạn phải sử dụng app.usetrên app.routertrước express.bodyParsernhưng mã của bạn cho thấy rõ ràng nó SAU. Vậy đó là cái gì?
Levi Roberts

1
Xin lỗi bạn. Bạn cần sử dụng app.router sau express.bodyParser.
HenioJR

1
Cảm ơn bạn @LeviRoberts
HenioJR

4
var bodyParser = require('body-parser');
app.use(bodyParser.json());

Điều này đã cứu ngày của tôi.


4

Vấn đề này có thể là do bạn chưa sử dụng trình phân tích cú pháp cơ thể ( liên kết )

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

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

3

Tôi đã giải quyết nó bằng:

app.post('/', bodyParser.json(), (req, res) => {//we have req.body JSON
});

3

Đây cũng là một khả năng : Đảm bảo rằng bạn nên viết mã này trước tuyến đường trong tệp app.js (hoặc index.js) của bạn.

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

2

Bạn có thể sử dụng trình phân tích cú pháp cơ thể nhanh.

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

2

Phiên bản mới nhất của Express đã có sẵn trình phân tích cú pháp cơ thể. Vì vậy, bạn có thể sử dụng:

const express = require('express);
... 
app.use(express.urlencoded({ extended: false }))
.use(express.json());

1

Trong trường hợp nếu bạn đăng thông báo SOAP, bạn cần sử dụng trình phân tích cú pháp cơ thể thô:

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

app.use(bodyParser.raw({ type: 'text/xml' }));

1

Xây dựng trên @ kevin-xue cho biết, loại nội dung cần phải được khai báo. Trong trường hợp của tôi, điều này chỉ xảy ra với IE9 vì XDomainRequest không đặt loại nội dung , vì vậy bodyparser và expressjs đã bỏ qua phần thân của yêu cầu.

Tôi đã khắc phục điều này bằng cách đặt loại nội dung một cách rõ ràng trước khi chuyển yêu cầu đến trình phân tích cú pháp cơ thể, như vậy:

app.use(function(req, res, next) {
    // IE9 doesn't set headers for cross-domain ajax requests
    if(typeof(req.headers['content-type']) === 'undefined'){
        req.headers['content-type'] = "application/json; charset=UTF-8";
    }
    next();
})
.use(bodyParser.json());

1

Tín dụng cho @spikeyang cho câu trả lời tuyệt vời (được cung cấp dưới đây). Sau khi đọc bài viết gợi ý kèm theo bài đăng, tôi quyết định chia sẻ giải pháp của mình.

Khi nào sử dụng?

Giải pháp yêu cầu bạn sử dụng bộ định tuyến tốc hành để thưởng thức nó .. vì vậy: Nếu bạn đã cố gắng sử dụng câu trả lời được chấp nhận mà không gặp may, chỉ cần sử dụng chức năng sao chép và dán chức năng này:

function bodyParse(req, ready, fail) 
{
    var length = req.header('Content-Length');

    if (!req.readable) return fail('failed to read request');

    if (!length) return fail('request must include a valid `Content-Length` header');

    if (length > 1000) return fail('this request is too big'); // you can replace 1000 with any other value as desired

    var body = ''; // for large payloads - please use an array buffer (see note below)

    req.on('data', function (data) 
    {
        body += data; 
    });

    req.on('end', function () 
    {
        ready(body);
    });
}

và gọi nó như:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

LƯU Ý: Đối với tải trọng lớn - vui lòng sử dụng bộ đệm mảng ( thêm @ MDN )


gói bodyParser thường được sử dụng và chuyển tải trọng thành một đối tượng cơ thể. như được cung cấp trong các câu trả lời khác
Schuere

1

Nếu bạn đang sử dụng một số công cụ bên ngoài để thực hiện yêu cầu, hãy đảm bảo thêm tiêu đề:

Content-Type: application/json


Điều này đã giúp tôi, tôi đã làm việc với Postman, cảm ơn bạn thân.
R. Gurung

1

Đối với bất kỳ ai mà không có câu trả lời nào ở trên đã làm việc cho tôi, tôi phải bật cors giữa front-end và express.

Bạn có thể làm điều này bằng cách:

  1. Tải xuống và bật tiện ích mở rộng CORS cho trình duyệt của bạn, chẳng hạn như:

    https://chrom.google.com.vn/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=vi

    cho Chrome,

hoặc bằng cách

  1. Thêm dòng

    var cors=require('cors');
    
    app.use(cors());

đến app.jstrang thể hiện của bạn . (Sau npm install cors)

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.