我使用JSON将数据发送到websocket。有时,websocket将许多消息视为一个,而event.data看起来像:
{
"entrypoint": "index.html",
"shell": "/src/my-app.html",
"fragments": [
"/src/my-app.html",
"/src/my-home.html",
"/src/my-shop.html"
],
"sourceGlobs": [
"src/**",
"src/**/*",
"src/structure/**/*",
"images/**/*",
"bower.json"
],
"includeDependencies": [
"manifest.json",
"bower_components/webcomponentsjs/webcomponents-lite.min.js"
]
}
所以我无法使用JSON.Parse解析它。如何处理这个问题?
答案 0 :(得分:2)
以下是一个自动恢复JSON解析器的示例,您可以使用它来解析连接的jsons:
function *multiJson(str) {
while (str) {
try {
yield JSON.parse(str);
str = '';
} catch(e) {
var m = String(e).match(/position\s+(\d+)/);
yield JSON.parse(str.slice(0, m[1]));
str = str.slice(m[1]);
}
}
}
//
let test = '{"message1":"message1"}{"message2":{"nested":"hi}{there"}}"third"[4,5,6]';
for (let x of multiJson(test))
console.log(x)
基本上,如果位置n
存在语法错误,它会尝试解析n
之前的所有内容以及之后的内容。
答案 1 :(得分:1)
如果你无法在发送方修复它,它总是这样,那么你可能会尝试修复它并用'}{'
替换'}\n{'
,拆分换行并有一个JSON字符串数组
var array = input.replace('}{', '}\n{').split('\n');
请注意,如果您的输入包含换行符,则必须使用其他字符或字符串:
var array = input.replace('}{', '}==XXX=={').split('==XXX==');
但它依赖的事实是你在字符串中的其他地方没有'}{'
,这可能不是真的。
更正确的方法,但更难的是计算不在字符串内的{
和}
,并且当您获得与}
相同的数量时{
然后在那里拆分字符串。
你需要做的是逐个字符地跟踪你是否在引号内,让每个{
增加一个计数器,}
递减一个计数器并在每次分割你的输入你的计数器达到零。
另一个hacky方法是尝试在每个可能的}
上拆分字符串,并尝试将子字符串解析为JSON,如果它有效,则使用它并从输入中删除。
答案 2 :(得分:1)
如果您对API有任何控制权,那么我强烈建议您将其修复。但是,如果你没有,请继续阅读。
我认为寻找"}"实际上并不是一个选项,因为你可以拥有嵌套对象,而}字符可能在字符串中,依此类推。
一种快速简便的方法是尝试解析以1个字符开头并逐个添加字符的字符串,直到JSON解析器不会失败。那时你将解析你的第一块数据。
将偏移移动到成功解析数据的末尾并重复。
可能不是一个优雅的解决方案或非常有效的解决方案,但你再次拥有非标准的数据格式。