req.body trống trên bài viết


256

Đột nhiên, điều này đã xảy ra với tất cả các dự án của tôi.

Bất cứ khi nào tôi tạo một bài đăng trong nodejs bằng cách sử dụng express và body-Parser req.bodylà một đối tượng trống.

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

var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded())

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

app.listen(2000);

app.post("/", function (req, res) {
  console.log(req.body) // populated!
  res.send(200, req.body);
});

Qua ajax và người đưa thư, nó luôn trống rỗng.

Tuy nhiên thông qua curl

$ curl -H "Content-Type: application/json" -d '{"username":"xyz","password":"xyz"}' http://localhost:2000/

nó hoạt động như dự định.

Tôi đã thử cài đặt thủ công Content-type : application/jsontrước đây nhưng sau đó tôi luôn nhận được400 bad request

Điều này đã khiến tôi phát điên.

Tôi nghĩ rằng đó là một cái gì đó được cập nhật trong trình phân tích cú pháp cơ thể nhưng tôi đã hạ cấp và nó không giúp được gì.

Bất kỳ trợ giúp đánh giá cao, cảm ơn.


16
Vì vậy, bạn đã cố gắng thiết lập rõ ràng Content-Typetrong postman? Nếu không, bạn có thể thử điều đó, vì tôi đã gặp vấn đề trước đó với người đưa thư không gửi a Content-Type.
mscdex

vâng tôi đã làm đó là khi tôi nhận được 400: json không hợp lệ
Joseph Tweetsey

@mscdex - cảm ơn tôi đã không đặt nội dung-tupe trong người đưa thư và đang trở nên điên rồ :)
Muzafar Ali

Đối với những người đang đến đây vì họ muốn gửi / tải tệp từ API của họ và do đó phải sử dụng dữ liệu biểu mẫu. Bạn cần một cái gì đó để xử lý dữ liệu biểu mẫu: npmjs.com/package/multer là gói khá phổ biến.
bhaskar

Không có vấn đề gì, người đưa thư không xử lý các số nguyên và giá trị nổi rất tốt. Nếu bạn có các giá trị số nguyên hoặc số float, hãy đảm bảo trích dẫn gấp đôi mọi thứ, cả khóa và giá trị
an.uso93

Câu trả lời:


272

Trong Postman của 3 tùy chọn có sẵn cho loại nội dung, chọn "X-www-form-urlencoding" và nó sẽ hoạt động.

Ngoài ra để loại bỏ thông báo lỗi thay thế:

app.use(bodyParser.urlencoded())

Với:

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

Xem https://github.com/expressjs/body-parser

Phần mềm trung gian 'trình phân tích cú pháp cơ thể' chỉ xử lý dữ liệu JSON và urlencode chứ không phải đa dữ liệu


Điều đó làm việc cho người đưa thư, tôi không chắc tại sao nó hoạt động với ajax vì tôi không thay đổi gì cả.
Joseph Tweetsey

Vì một số lý do, các bài đăng http qua Angular không cần phải được mã hóa URL, nhưng các cuộc gọi ajax đã làm. Có ai biết tại sao không?
youngrrrr

Điều này làm việc cho tôi, tại sao nó không hoạt động với mã hóa thô?
Daniel Kobe

9
bây giờ trình phân tích cú pháp cơ thể đã sẵn sàng với express.js chỉ cần sử dụngapp.use(express.json());
Sujeet Agrahari

Cảm ơn bạn rất nhiều! Mặc dù thời gian dài điều này đã được trả lời, nó vẫn có liên quan.
Spray'n'Pray

218

Với Postman, để kiểm tra các hành động đăng bài HTTP với tải trọng dữ liệu JSON thô, chọn rawtùy chọn và đặt các tham số tiêu đề sau:

Content-Type: application/json

Ngoài ra, hãy đảm bảo bọc bất kỳ chuỗi nào được sử dụng làm khóa / giá trị trong tải trọng JSON của bạn trong dấu ngoặc kép.

Các body-parsergói phần mềm sẽ phân tích đa dòng trọng tải JSON liệu tốt.

{
    "foo": "bar"
}

Đã thử nghiệm trong Chrome v37 và v41 với tiện ích mở rộng Postman v0.8.4.13 ( body-parserv1.12.2 và expressv4.12.3) với thiết lập bên dưới:

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

// configure the app to use bodyParser()
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

// ... Your routes and methods here

Postman raw tải trọng json


Ôi trời, làm thế nào tôi nhớ rằng tôi đã dán một đối tượng JS theo nghĩa đen chứ không phải là một đối tượng JSON được định dạng đúng ...: -S ... cảm ơn bạn!
Wes Johnson

Bao bọc bất kỳ chuỗi nào được sử dụng làm khóa / giá trị trong dấu ngoặc kép ... Dễ bỏ lỡ nhưng hoàn toàn là một bộ ngắt thỏa thuận! Cảm ơn bạn.
loxyboi

Sử dụng tốt các ảnh chụp màn hình.
Xan-Kun Clark-Davis

Khi sử dụng form-datatrong Postman để đăng dữ liệu, tôi luôn nhận được {}trong req.body. Tôi có nên đặt Content-Typetùy chọn?
mingchau

56

Tôi đã mắc một lỗi thực sự ngớ ngẩn và quên xác định namecác thuộc tính cho đầu vào trong tệp html của mình.

Vì vậy, thay vì

<input type="password" class="form-control" id="password">

Tôi có cái này

<input type="password" class="form-control" id="password" name="password">

Bây giờ request.bodyđược điền như thế này:{ password: 'hhiiii' }


1
B Bam. Đó là vấn đề. Cảm ơn!
Matt West

Đó chính xác là vấn đề của tôi, một hình thức nhập không có giá trị tên, đã dành hàng giờ cố gắng để tìm ra nó. Cảm ơn.
karensantana

37

Tôi phát hiện ra rằng nó hoạt động khi gửi với loại nội dung

"ứng dụng / json"

kết hợp với phía máy chủ

app.use(bodyParser.json());

Bây giờ tôi có thể gửi qua

var data = {name:"John"}
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", theUrl, false); // false for synchronous request
xmlHttp.setRequestHeader("Content-type", "application/json");
xmlHttp.send(data);

và kết quả có sẵn request.body.nametrên máy chủ.


Cảm ơn các upvote. Tôi thực sự nghĩ rằng đây là cách sạch nhất, mặc dù không phải là giải pháp đơn giản nhất, vì bạn nên gửi đúng loại nội dung. Tôi nghĩ.
Xan-Kun Clark-Davis

đây là câu trả lời!
Gel

Trong trường hợp của tôi, tôi đã phải đổi nó thànhxmlHttp.send(JSON.stringify(data));
endo64

18

Tôi đã gặp phải vấn đề này ngày hôm nay và điều đã khắc phục là loại bỏ tiêu đề kiểu nội dung trong Postman! Rất lạ. Thêm nó ở đây trong trường hợp nó giúp ai đó.

Tôi đã theo dõi hướng dẫn của BeerLocker tại đây: http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/


2
Tôi gặp vấn đề tương tự. có tiêu đề "không được kiểm tra" (và bị mờ đi) là không đủ, tôi phải loại bỏ nó hoàn toàn. ngay cả khi nút nguồn "</>" cho thấy rằng tôi đã không gửi tiêu đề đó với Kiểu nội dung ở trạng thái không được kiểm tra, nó vẫn cần phải được loại bỏ hoàn toàn.
theRemix

Tôi không thể tìm ra cách loại bỏ các tiêu đề mặc định trong tiện ích chrome của người đưa thư ... bạn có đang sử dụng ứng dụng không?
WestleyArgentum

Ồ, tôi đã cài đặt ứng dụng và nó hoạt động tốt hơn nhiều so với tiện ích mở rộng. Xin lỗi vì sự ồn ào.
WestleyArgentum

12

Bạn phải kiểm tra xem phần mềm trung gian phân tích cú pháp cơ thể có được đặt đúng với loại yêu cầu không (json, urlencoding).

Nếu bạn đã thiết lập,

app.use(bodyParser.json());

sau đó trong postman bạn phải gửi dữ liệu dưới dạng thô.

https://i.stack.imgur.com/k9IdQ.png ảnh chụp màn hình người đưa thư

Nếu bạn đã thiết lập,

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

sau đó nên chọn tùy chọn 'x-www-form-urlencoding'.


Còn cả hai thì sao? (bodyParser.urlencoding và bodyParser.json ()) ... tôi có thể sử dụng cái nào trong postman?
TommyLeong

9

Vấn đề của tôi là tôi đã tạo ra tuyến đường đầu tiên

// ...
router.get('/post/data', myController.postHandler);
// ...

và đăng ký phần mềm trung gian sau tuyến đường

app.use(bodyParser.json());
//etc

do cấu trúc ứng dụng & sao chép và dán dự án với nhau từ các ví dụ.

Khi tôi đã sửa lỗi để đăng ký phần mềm trung gian trước tuyến đường, tất cả đều hoạt động.


cảm ơn fiat, với thứ tự đúng và sử dụng tab thô cuối cùng nó đã hoạt động với tôi
Alex

4

Ngay cả khi tôi học node.js lần đầu tiên khi tôi bắt đầu học nó qua ứng dụng web, tôi đã có tất cả những điều này được thực hiện tốt trong biểu mẫu của mình, tôi vẫn không thể nhận được các giá trị trong yêu cầu bài đăng. Sau một thời gian dài gỡ lỗi, tôi biết rằng ở dạng tôi đã cung cấp enctype="multipart/form-data"do tôi không thể nhận được các giá trị. Tôi chỉ đơn giản là loại bỏ nó và nó làm việc cho tôi.


vâng, điều này cũng hoạt động để có được phần thân biểu mẫu nhưng sau đó gây ra một vấn đề khác với biểu mẫu của tôi - về cơ bản, tệp không thể được tải lên vì điều này đòi hỏienctype="multipart/form-data"
tsando

btw, chỉ để thêm vào nhận xét trên của tôi, tôi đã quản lý để làm việc này với multer- xem tài liệu trên npmjs.com/package/multer
tsando

3

Có vẻ như nếu bạn không sử dụng bất kỳ encType (mặc định là application/x-www-form-urlencoded) thì bạn sẽ nhận được các trường nhập văn bản nhưng bạn sẽ không nhận được tệp.

Nếu bạn có một hình thức mà bạn muốn đăng nhập văn bản và tệp thì hãy sử dụng multipart/form-dataloại mã hóa và ngoài đó sử dụng multerphần mềm trung gian. Multer sẽ phân tích đối tượng yêu cầu và chuẩn bị req.filecho bạn và tất cả các trường đầu vào khác sẽ có sẵn thông qua req.body.


1
cảm ơn - multerthực sự là giải pháp cho vấn đề của tôi Sẽ tốt hơn nếu bạn có thể thêm một ví dụ về cách sử dụng điều này như một phần câu trả lời của bạn
tsando

2

Một vấn đề tương tự đã xảy ra với tôi, tôi chỉ đơn giản là trộn thứ tự của các thông số gọi lại. Hãy chắc chắn rằng bạn đang thiết lập các chức năng gọi lại theo đúng thứ tự. Ít nhất là cho bất cứ ai có cùng một vấn đề.

router.post('/', function(req, res){});

2

Đảm bảo ["key": "type", "value": "json"] & ["key": "Content-Type", "value": "application / x-www-form-urlencoding"] tiêu đề yêu cầu người đưa thư


2

Tôi đã giải quyết điều này bằng cách sử dụng multernhư đề xuất ở trên, nhưng họ đã bỏ lỡ việc đưa ra một ví dụ hoạt động đầy đủ, về cách thực hiện việc này. Về cơ bản điều này có thể xảy ra khi bạn có một nhóm biểu mẫu với enctype="multipart/form-data". Đây là HTML cho mẫu tôi đã có:

<form action="/stats" enctype="multipart/form-data" method="post">
  <div class="form-group">
    <input type="file" class="form-control-file" name="uploaded_file">
    <input type="text" class="form-control" placeholder="Number of speakers" name="nspeakers">
    <input type="submit" value="Get me the stats!" class="btn btn-default">            
  </div>
</form>

Và đây là cách sử dụng multerđể lấy các giá trị và tên của biểu mẫu này với Express.jsnode.js:

var multer  = require('multer')
var upload = multer({ dest: './public/data/uploads/' })
app.post('/stats', upload.single('uploaded_file'), function (req, res) {
   // req.file is the name of your file in the form above, here 'uploaded_file'
   // req.body will hold the text fields, if there were any 
   console.log(req.file, req.body)
});

1

Tôi đã có cùng một vấn đề một vài phút trước đây, tôi đã thử mọi cách có thể trong các câu trả lời ở trên nhưng bất kỳ câu hỏi nào cũng có hiệu quả.

Điều duy nhất tôi đã làm, là nâng cấp phiên bản Node JS, tôi không biết rằng việc nâng cấp có thể ảnh hưởng đến một cái gì đó, nhưng nó đã làm.

Tôi đã cài đặt phiên bản Node JS 10.15.0( phiên bản mới nhất), tôi đã quay lại 8.11.3và mọi thứ hiện đang hoạt động. Có lẽ body-parsermô-đun nên có một sửa chữa về điều này.


1

Tôi không có tên trong Đầu vào của mình ... yêu cầu của tôi trống rỗng ... rất vui vì điều đó đã kết thúc và tôi có thể tiếp tục viết mã. Cảm ơn mọi người!

Trả lời Tôi đã sử dụng bởi Jason Kim:

Vì vậy, thay vì

<input type="password" class="form-control" id="password">

Tôi có cái này

<input type="password" class="form-control" id="password" name="password">

1

bạn không nên làm JSON.stringify(data)trong khi gửi qua AJAX như bên dưới.

Đây không phải là mã chính xác:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: JSON.stringify(data),
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}   

Mã chính xác là:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: data,
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}

một điều quan trọng cần lưu ý ở đây là về loại hình, hãy đảm bảo bạn viết hoa chữ "POST". Tôi đã thấy các trường hợp chỉ sử dụng "bài đăng" đã dẫn đến req.body trống.
Matt C.

1

Nếu bạn đang làm với người đưa thư, vui lòng xác nhận những thứ này khi bạn yêu cầu API

nhập mô tả hình ảnh ở đây


0

Tôi đã sử dụng restify thay vì express và gặp vấn đề tương tự. Giải pháp là làm:

server.use(restify.bodyParser());


0

Thay đổi app.use(bodyParser.urlencoded());mã của bạn thành

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

và trong postman, trong Content-Typegiá trị thay đổi tiêu đề từ application/x-www-form-urlencodedđếnapplication/json

Ta :-)


0

Cảm ơn tất cả các câu trả lời tuyệt vời của bạn! Đã dành khá nhiều thời gian để tìm kiếm một giải pháp, và về phía tôi, tôi đã mắc một lỗi cơ bản: Tôi đã gọi bodyParser.json()từ trong hàm:

app.use(['/password'], async (req, res, next) => {
  bodyParser.json()
  /.../
  next()
})

Tôi chỉ cần làm app.use(['/password'], bodyParser.json())và nó đã làm việc ...


0

Trong người đưa thư, ngay cả sau khi làm theo câu trả lời được chấp nhận, tôi đã nhận được một cơ thể yêu cầu trống. Vấn đề hóa ra là không vượt qua một tiêu đề được gọi là

Content-Length : <calculated when request is sent>

Tiêu đề này được trình bày theo mặc định (cùng với 5 cái khác) mà tôi đã tắt. Cho phép điều này và bạn sẽ nhận được cơ thể yêu cầu.


0

Vấn đề của tôi là tạo ra tuyến đường trước tiên require("./routes/routes")(app); tôi đã chuyển nó đến cuối mã trước đó app.listen và nó đã hoạt động!

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.