将 JSON 数据(带有节点请求)发布到 Express 服务器以保存到 MongoDB 时出现问题
Trouble with posting JSON data (with node request) to Express server for saving into MongoDB
我使用 MongoDB 作为我的 node/Express 应用程序的后端数据库。总结一下我面临的问题,我不知道如何在我的 Express 应用程序中设置 body-parser 配置,因为服务器端应用程序没有收到完整的 JSON posted客户端应用程序(也是 node.js 应用程序)。在大多数情况下,客户端将请求正文中的 JSON 发送到 RESTful 端点。例外是需要上传文件的单一情况,因为这是一个多部分主体,我在服务器端使用 request and form-data to build that type of request and using multer 来处理多部分请求,因为 body-parser 不处理此类请求。
在服务器端 (Express),我对 Express 应用程序进行了以下配置:
let app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
在节点客户端上,我使用以下代码构建一个 JSON 样式的 JavaScript 对象,并将其 post 连接到 RESTful 端点:
我在客户端编写请求时遇到困难,node-request:
// class is a JavaScript/JSON object within scope of this code
let req = request.post({
//headers: { 'Content-Type': 'application/json' },
url: 'http://localhost:3000/classes',
//form: class
form: JSON.stringify(class)
}, function (err, resp, body) {
if (err) {
throw err;
}
});
请注意,我通过将内容类型显式指定为 application/JSON
以及使用 JSON.stringify
将 JavaScript 对象转换为 JSON 字符串。 MongoDB 集合 (class
) 存储以下类型的文档,其中包含 外键 到其他两个集合(subject
和 student
):
{
"_id" : ObjectId("57758f15f68da08c254ebee1"),
"name" : "Grade 5 - Section A",
"scores" : [{
"studentId" : ObjectId("5776bd36ffc8227405d364d2"),
"performance": [{
"subjectId" : ObjectId("577694ecbf6f3a781759c54a"),
"score" : 86,
"maximum" : 100,
"grade" : "B+"
}]
}]
}
在服务器日志中,我看到以下错误:
Tue, 05 Jul 2016 04:34:46 GMT classReportApp:routes:classes class received from client: { _id: 577b38e65967097c25876764, scores: [] }
RangeError: Invalid status code: 0
at ServerResponse.writeHead (_http_server.js:192:11)
at ServerResponse.writeHead (C:\Development\classReportApp\node_modules\morgan\node_modules\on-headers\index.js:55:19)
at ServerResponse._implicitHeader (_http_server.js:157:8)
at ServerResponse.OutgoingMessage.end (_http_outgoing.js:566:10)
at ServerResponse.send (C:\Development\classReportApp\node_modules\express\lib\response.js:205:10)
at ServerResponse.json (C:\Development\classReportApp\node_modules\express\lib\response.js:250:15)
at C:\Development\classReportApp\server-process\app.js:80:26
at Layer.handle_error (C:\Development\classReportApp\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (C:\Development\classReportApp\node_modules\express\lib\router\index.js:310:13)
at C:\Development\classReportApp\node_modules\express\lib\router\index.js:280:7
at Function.process_params (C:\Development\classReportApp\node_modules\express\lib\router\index.js:330:12)
这很奇怪,因为 scores 子文档数组是空的 (scores: []
),而在客户端,我发送了一个非空数组里面有一些学生的表演元素。
我是否违反了 post JSON Express 应用程序的正确方式?我该如何解决这个问题?
编辑:2016 年 7 月 5 日
我将主体解析器中间件配置更改为使用 extended: true
。
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
node.js仍然使用node-request模块组合发送POST请求,使用代码如下:
let req = request({
url: 'http://localhost:3000/classes',
method: 'POST',
json: class
}, function (err, resp, body) {
if (err) {
throw err;
}
else {
// process response
}
});
这现在有效,但让我感到困惑的是,由于内容类型是 application/json,bodyParser.urlencoded({ extended: true })
(或假)有什么关系?
在发送前尝试 .toJSON() 方法超过 class。
问题出在您的第一个请求中 form: JSON.stringify(class)
。 form
采用 url 编码形式输入,字符串化 json 将不起作用。检查 content-type header (application/x-www-form-urlencoded)
json: class
在您的第二个代码段中工作,因为它处理 json 数据并正确设置正确的内容类型 header。
我使用 MongoDB 作为我的 node/Express 应用程序的后端数据库。总结一下我面临的问题,我不知道如何在我的 Express 应用程序中设置 body-parser 配置,因为服务器端应用程序没有收到完整的 JSON posted客户端应用程序(也是 node.js 应用程序)。在大多数情况下,客户端将请求正文中的 JSON 发送到 RESTful 端点。例外是需要上传文件的单一情况,因为这是一个多部分主体,我在服务器端使用 request and form-data to build that type of request and using multer 来处理多部分请求,因为 body-parser 不处理此类请求。
在服务器端 (Express),我对 Express 应用程序进行了以下配置:
let app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
在节点客户端上,我使用以下代码构建一个 JSON 样式的 JavaScript 对象,并将其 post 连接到 RESTful 端点:
我在客户端编写请求时遇到困难,node-request:
// class is a JavaScript/JSON object within scope of this code
let req = request.post({
//headers: { 'Content-Type': 'application/json' },
url: 'http://localhost:3000/classes',
//form: class
form: JSON.stringify(class)
}, function (err, resp, body) {
if (err) {
throw err;
}
});
请注意,我通过将内容类型显式指定为 application/JSON
以及使用 JSON.stringify
将 JavaScript 对象转换为 JSON 字符串。 MongoDB 集合 (class
) 存储以下类型的文档,其中包含 外键 到其他两个集合(subject
和 student
):
{
"_id" : ObjectId("57758f15f68da08c254ebee1"),
"name" : "Grade 5 - Section A",
"scores" : [{
"studentId" : ObjectId("5776bd36ffc8227405d364d2"),
"performance": [{
"subjectId" : ObjectId("577694ecbf6f3a781759c54a"),
"score" : 86,
"maximum" : 100,
"grade" : "B+"
}]
}]
}
在服务器日志中,我看到以下错误:
Tue, 05 Jul 2016 04:34:46 GMT classReportApp:routes:classes class received from client: { _id: 577b38e65967097c25876764, scores: [] }
RangeError: Invalid status code: 0
at ServerResponse.writeHead (_http_server.js:192:11)
at ServerResponse.writeHead (C:\Development\classReportApp\node_modules\morgan\node_modules\on-headers\index.js:55:19)
at ServerResponse._implicitHeader (_http_server.js:157:8)
at ServerResponse.OutgoingMessage.end (_http_outgoing.js:566:10)
at ServerResponse.send (C:\Development\classReportApp\node_modules\express\lib\response.js:205:10)
at ServerResponse.json (C:\Development\classReportApp\node_modules\express\lib\response.js:250:15)
at C:\Development\classReportApp\server-process\app.js:80:26
at Layer.handle_error (C:\Development\classReportApp\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (C:\Development\classReportApp\node_modules\express\lib\router\index.js:310:13)
at C:\Development\classReportApp\node_modules\express\lib\router\index.js:280:7
at Function.process_params (C:\Development\classReportApp\node_modules\express\lib\router\index.js:330:12)
这很奇怪,因为 scores 子文档数组是空的 (scores: []
),而在客户端,我发送了一个非空数组里面有一些学生的表演元素。
我是否违反了 post JSON Express 应用程序的正确方式?我该如何解决这个问题?
编辑:2016 年 7 月 5 日
我将主体解析器中间件配置更改为使用 extended: true
。
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
node.js仍然使用node-request模块组合发送POST请求,使用代码如下:
let req = request({
url: 'http://localhost:3000/classes',
method: 'POST',
json: class
}, function (err, resp, body) {
if (err) {
throw err;
}
else {
// process response
}
});
这现在有效,但让我感到困惑的是,由于内容类型是 application/json,bodyParser.urlencoded({ extended: true })
(或假)有什么关系?
在发送前尝试 .toJSON() 方法超过 class。
问题出在您的第一个请求中 form: JSON.stringify(class)
。 form
采用 url 编码形式输入,字符串化 json 将不起作用。检查 content-type header (application/x-www-form-urlencoded)
json: class
在您的第二个代码段中工作,因为它处理 json 数据并正确设置正确的内容类型 header。