在JSON的第1个位置发现意外的标记“o”

4
我经常在下面这段代码中遇到错误:

function openWebsocket(url) {
    var ws;
    ws = $websocket(url);
    ws.onOpen(function(event) {
        console.log(' Websocket connection established:', event);
    });
    ws.onMessage(function(message) {
        var userObj   = UserFactory.getUserObject();
        var settings  = userObj.alert_settings;

        // The JSON parsing...
        var parsedMsg = JSON.parse(message.data);
        var alert     = JSON.parse(parsedMsg);
        var date      = new Date(parseFloat(alert.start_epoch+'000'));
        alert.hour    = date.getHours() +':'+date.getMinutes();
        alert.percent_change = Math.round(alert.percent_change);

        var shouldPush = main_alert_filter(settings, alert);
        updateFeed(alerts, shouldPush, alert);
    });
}

我查看了解析JSON时出现“意外的令牌o”错误我一直收到“未捕获的SyntaxError:意外的令牌o”

但是,两个答案都没有帮助。当我首先运行JSON.parse(message.data)时,我会得到一个字符串而不是对象。因此,我必须再次运行JSON.parse才能最终得到真正的对象。

enter image description here

这就是message.data的样子:

" "{\"term\": \"\\\"nike\\\"\", \"percent_change\": 125, \"hour\": \"10:9\", \"term_id\": 2890413, \"start_epoch\": 1420474140, \"term_trend_id\": 793950, \"end_epoch\": 1420477740, \"formatted_date_difference\": \"January 5, 2015\", \"tickers\": [\"NKE\", \"$PUM\", \"ADDYY\", \"LULU\", \"UA\", \"HIBB\"], \"twitter_preview\": \"\", \"type\": \"spike\", \"approved\": 1, \"search_preview\": [\"\"]}" "

现在,在第一次解析之后,parsedMsg是一个看起来像这样的字符串:

{"term": "minimum wage +increase", "percent_change": 729, "hour": "9:14", "term_id": 2522115, "start_epoch": 1447168440, "term_trend_id": 657898, "end_epoch": 1447175700, "formatted_date_difference": "November 10, 2015", "tickers": ["$JAB", "$SLCY", "AAL", "AAPL", "ABCD", "ABTL", "ADDYY", "ADM", "AEO", "AFCO", "AHC"......

最后,我需要一个实际的对象,所以我必须再次运行JSON.parse才能得到这个:

Object {term: "minimum wage +increase", percent_change: 729, hour: "9:14", term_id: 2522115, start_epoch: 1447168440…}

另外需要注意的是,当我在Chrome中逐步执行时,我从未遇到过该错误。只有在我没有设置断点时才会发生。这可能是一种竞争条件问题吗?例如,它尝试解析还没有准备好解析的内容?


更新

好的,看起来有时JSON是无效的,有时不是。目前,使用以下代码片段,我没有出现错误,您有什么想法?

if (typeof alert === 'object') {
    // do nothing...
} else {
    var alert = JSON.parse(alert);
}

大多数情况下,JSON.parse(message.data)alert 结果是一个 string,因此我需要另一个检查来进行二次解析。

1
当我使用JSON.parse(...)解析你的第一个字符串(一个有效的子集),我得到了最终的对象,而不是你所声称得到的中间字符串。如果我解析那个对象,我会得到你得到的错误... - seairth
你的 parse JSON 不完整!请分享完整的 JSON 结果,以便我们找到错误。 - M.Tanzil
抱歉,它已经完成了,只是太大了,我不想发布整个东西。 - Leon Gaban
1
你更新后的 message.data 不可能是实际数据,或者说它确实是吗?第一个引号后和最后一个引号前有换行符。那些三个反斜杠 - 这才是数据中真正的内容吗? - Michael Geary
1
@LeonGaban,你更新的 message.data 完全无效,开头有两个 ",这是无效的字符串,解析为 JSON 格式还有很长的路要走。 - M.Tanzil
显示剩余3条评论
3个回答

3
为什么要第二次解析Json,它已经在第一次尝试中被解析了。请看代码片段。

var obj = "{\"term\": \"minimum wage +increase\", \"percent_change\": 729, \"hour\": \"9:14\", \"term_id\": 2522115, \"start_epoch\": 1447168440, \"term_trend_id\": 657898, \"end_epoch\": 1447175700, \"formatted_date_difference\": \"November 10, 2015\", \"tickers\": [\"$JAB\", \"$SLCY\", \"AAL\", \"AAPL\", \"ABCD\", \"ABTL\", \"ADDYY\"]}";
$(function(){
  var data = JSON.parse(obj);
  alert(typeof data);
  console.log(data.tickers[0] +" -> an item in `tickers` array");
  console.log(data.tickers);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


我不得不再次解析它,因为第一次解析时它仍然是“typeof string”。所以当我在alert.user上设置字符串时,会出现错误。 - Leon Gaban
@LeonGaban 它的类型是 object,检查更新后的 snippet,你可以访问对象中的任何内容。同时,一旦将字符串解析为 JSON 对象,它就已经被解析了,不需要再次解析。如果你仍然有问题,可以向我们展示整个对象。希望这可以帮助你 :) - M.Tanzil
检查你的浏览器控制台,你可能会找到答案,并且你会很好地理解你的第一个格式化JSON对象...看一下吧。谢谢 - M.Tanzil
刚刚更新了我的问题,并附上了完整的 message.data JSON。 - Leon Gaban

2
你用 message.data 指定的 JSON 字符串格式不正确。可能是因为服务器在建立连接期间/之后发送了多部分消息。
我建议你在 OnMessage 函数中打印接收到的消息对象并分析它们是否是完整的有效 JSON 字符串。

刚刚更新了我的问题,并附上了完整的 message.data JSON。 - Leon Gaban

0

看起来你的 message.data 是不完整的。

查看一下你正在使用的库文档,也许你应该收集数据直到它的结束?也许有一些 onEnd 方法吗?


抱歉,它是完整的,只是非常庞大,所以我不想发布整个JSON,但如果需要,我可以这样做。 - Leon Gaban
你尝试过在检查器控制台中解析响应吗?我认为你不应该解析两次 :) 也许有一些格式不正确的数据,比如未转义的 " 字符。 - rtbm
@MarcinBogusz:如果原始的JSON数据被字符串化了两次,那么肯定是可以的。例如:JSON.stringify( JSON.stringify({ "foo": "bar" }) )。这将给您一个字符串:"{\"foo\":\"bar\"}"。(这里的外部引号是字符串的一部分,而不是包含字符串的引号。)解析一次会给您一个字符串(而不是对象){"foo":"bar"};再次解析它会给您原始的对象{foo: "bar"} - Michael Geary
作为另一个例子,JSON.stringify(true) 返回字符串 trueJSON.stringify( JSON.stringify(true) ) 返回字符串 "true"(这里的引号是字符串的一部分)。对此结果进行一次解析返回字符串 true,再对其进行解析返回布尔值 true,例如 JSON.parse( JSON.parse( JSON.stringify( JSON.stringify(true) ) ) ) - Michael Geary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接