我正在学习nodeJS。
我尝试了其他stackoverlow问题和答案,但没有找到解决方案。我在最近2天坚持这一点。
以下是问题的开始
angular js code:
$scope.queAns = [{"answer":"truyt","question":"How do you keep list elements straight in an HTML file?"},{"answer":"asc","question":"A sum of money at simple interest amounts to Rs. 815 in 3 years and to Rs. 854 in 4 years. The sum is:"}];
$http({
method : 'POST',
url : "http://localhost:8888/answerList",
withCredentials: true,
data: $scope.queAns,
headers : {'Content-Type' : 'application/x-www-form-urlencoded'}
}).then(function (response) {
console.log(response.data);
}, function (error) {
alert("Something went wrong.");
});
NodeJs代码:
var http = require('http');
var fs = require('fs');
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.post('/answerList',urldecodedParser, function(req, res) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Content-Type', 'application/json');
console.log(req.body);
res.send(req.body);
})
我的输出为
{"{\"answer\":\"truyt\",\"question\":\"How do you keep list elements straight in an HTML file?\"},{\"answer\":\"asc\",\"question\":\"A sum of money at simple interest amounts to Rs. 815 in 3 years and to Rs. 854 in 4 years. The sum is:\"}":""}
我希望输出为:
[{"answer":"truyt","question":"How do you keep list elements straight in an HTML file?"},{"answer":"asc","question":"A sum of money at simple interest amounts to Rs. 815 in 3 years and to Rs. 854 in 4 years. The sum is:"}]
任何帮助???
答案 0 :(得分:0)
在AJAX出现之前,网站使用<input>
元素中的<form>
个元素来发出请求。每个<input>
都有name
和value
,其编码为:
name1=value1&name2=value2&name3=value3
如果使用GET请求提交了<form>
,则此编码参数数据将仅附加到URL。另一方面,如果它是使用POST请求提交的,则会使用content-type
application/x-www-form-urlencoded
作为请求正文发送。
回到今天,这种格式仍然存在并且仍可用于将数据传输到服务器。在Express中,中间件bodyParser.urlencoded
会将使用application/x-www-form-urlencoded
格式的请求主体解码为平面JS对象。使用上面的例子,你最终会得到类似的结果:
req.body = {
name1: 'value1',
name2: 'value2',
name3: 'value3'
}
如果传递的参数没有值,例如name1
中的name1&name2=value2
,它将被视为值为空字符串,因此:
req.body = {
name1: '',
name2: 'value2'
}
现在让我们假设我们将JSON数据{"answer":true}
作为我们的请求体发送,但我们错误地将application/x-www-form-urlencoded
用于content-type
。解析器会将{"answer":true}
视为与前一个示例中的name1
相同,并将其解析为:
req.body = {
'{"answer":true}': ''
}
对于人类来说,显然有一些JSON在这里,但对于解析器的冷酷,不可原谅的逻辑,文本{"answer":true}
没有特殊意义,它只是将其视为参数名称。
如果我们尝试使用以下方法在响应中反弹:
res.send(req.body);
将进行JSON编码以提供响应:
{"{\"answer\":true}":""}
这就是你所看到的,虽然有更长的JSON。目前我无法解释您的示例中方括号的位置,我希望在四肢看到[
和]
,但看起来似乎正在消耗它们。
要解决此问题,我们首先需要修复content-type
。而不是使用application/x-www-form-urlencoded
,它应该是application/json
。然后我们需要在服务器上使用适当的解析器,即bodyParser.json
,例如:
app.post('/answerList', bodyParser.json(), function(req, res) {
通常bodyParser
将单独包含,因此所有请求都可以共享它。只有content-type
application/json
的请求才会受到影响,因此不会对未使用JSON的请求造成任何不利影响:
app.use(bodyParser.json());
app.post('/answerList', function(req, res) {
我强烈建议您阅读https://expressjs.com/en/resources/middleware/body-parser.html
上的文档