JSON 字符串上的 JSON 解析抛出“无法将对象转换为原始值”
Posted
技术标签:
【中文标题】JSON 字符串上的 JSON 解析抛出“无法将对象转换为原始值”【英文标题】:JSON parse on a JSON string throws "Cannot convert object to primitive value" 【发布时间】:2018-05-19 05:38:55 【问题描述】:server.js
使用正文解析器中间件、把手和快递
路线
module.exports = function (app)
app.post('/questionnaire/submit', function (req, res) // Ajax Call
var data = JSON.parse(req.body);
res.send();
);
;
客户
function submitData() // Send a data object to the server
$.ajax(
type: 'POST',
url: '/questionnaire/submit',
dataType: "json",
data: JSON.stringify(
satisfactory: "text 1",
improvement: "text 2",
rating: 0.7
)
).done(function ()
$(location).attr('href', '/sendOff');
).fail(function ()
);
当记录 req.body
时,我得到一个 JSON 字符串
'"satisfactory":"text 1","improvement":"text 2","rating":0.7': ''
我尝试将此字符串解析为一个对象。当我这样做时,我会收到此错误消息
TypeError: Cannot convert object to primitive value at JSON.parse (<anonymous>) at C:\Users\mah\Desktop\FeedbackTool\Server\Routes\questionnaire.js:12:25 at Layer.handle [as handle_request] (C:\Users\mah\node_modules\express\lib\router\layer.js:95:5) at next (C:\Users\mah\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (C:\Users\mah\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (C:\Users\mah\node_modules\express\lib\router\layer.js:95:5) at C:\Users\mah\node_modules\express\lib\router\index.js:281:22 at Function.process_params (C:\Users\mah\node_modules\express\lib\router\index.js:335:12) at next (C:\Users\mah\node_modules\express\lib\router\index.js:275:10) at C:\Users\mah\node_modules\body-parser\lib\read.js:130:5
那么如何将字符串解析为对象?
通常我会执行JSON.parse(req.body)
。
【问题讨论】:
“在记录 req.body 时我得到一个 JSON 字符串” 这对我来说看起来不像 JSON 字符串。它看起来像是带有 JSON 的东西,但开头的 '
不是 JSON(而且结尾看起来很奇怪)。
@TJCrowder 是 '<json>': ''
形式的字符串,即一个完整的JSON文档作为另一个JSON文档的key,除非在JSON中不能选择使用'
,所以外部文档无效。
@meagar:属性名称和其他字符串在 JSON 中总是用双引号引起来。 (编辑:啊,你编辑了。:-))而且由于 OP 使用的是JSON.stringify
,我们知道它不会有单引号字符串...
【参考方案1】:
dataType
没有说明您发送的数据类型,它说明了您期望的响应类型。您需要在您的ajax
通话中说明您正在通过contentType: "application/json"
发送JSON。 the documentation 中的详细信息。 (到目前为止,你不是第一个或唯一一个被 dataType
命名绊倒的人。)
这是问题的一半。另一半见Stamos' answer。
【讨论】:
【参考方案2】:由于您使用的是body-parser
中间件,因此您不必再次解析req.body
,因为它已经被body-parser
解析了
例子
如果你用过
app.use(bodyParser.json())
那么你只需要这样做
module.exports = function (app)
app.post('/questionnaire/submit', function (req, res) // Ajax Call
var data = req.body; // this is already parsed and is an object
res.send();
);
;
正如@T.J.所指出的。 Crowder 你也应该发送正确的contentType
所以body-parser
知道它的json
function submitData() // Send a data object to the server
$.ajax(
type: 'POST',
url: '/questionnaire/submit',
contentType: 'application/json',
data: JSON.stringify(
satisfactory: "text 1",
improvement: "text 2",
rating: 0.7
)
).done(function ()
$(location).attr('href', '/sendOff');
).fail(function ()
);
【讨论】:
好点。这是问题的另一半(前半部分是sending the rightcontentType
)。【参考方案3】:
您需要设置正确的 contentType:
$.ajax(
type: 'POST',
url: '/questionnaire/submit',
contentType: 'application/json',
data: JSON.stringify( satisfactory: "text 1", rating: 0.7 )
);
app.post('/questionnaire/submit', function (req, res) // Ajax Call
var data = JSON.parse(req.body);
console.log(data.rating); // 0.7
res.send(data);
);
此外,使用body-parser
,您可以避免在服务器端调用JSON.parse
the link。
【讨论】:
但是我没有提到body-parser
中间件...这真的很重要以上是关于JSON 字符串上的 JSON 解析抛出“无法将对象转换为原始值”的主要内容,如果未能解决你的问题,请参考以下文章