【问题标题】:JSON parse on a JSON string throws "Cannot convert object to primitive value"JSON 字符串上的 JSON 解析抛出“无法将对象转换为原始值”
【发布时间】: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 是{ '&lt;json&gt;': '' }形式的字符串,即一个完整的JSON文档作为另一个JSON文档的key,除非在JSON中不能选择使用',所以外部文档无效。
  • @meagar:属性名称和其他字符串在 JSON 中总是用双引号引起来。 (编辑:啊,你编辑了。:-))而且由于 OP 使用的是JSON.stringify,我们知道它不会有单引号字符串...

标签: javascript json node.js


【解决方案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 () {
    
        });
    }
    

    【讨论】:

    【解决方案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中间件...这真的很重要
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 2013-01-10
    相关资源
    最近更新 更多