带有双反斜杠的节点中看似奇怪的JSON.parse行为

时间:2020-01-15 23:37:53

标签: javascript node.js json

一个同事正试图解析在另一个系统中生成的json字符串,并遇到了我们无法解释的行为。我在这里用一个非常小的代码示例复制了这个问题:

// running in node >= 8 (tried both 8 and 12)

const str1 = '{ "test": "path\\test" }';
const str2 = '{ "test": "path\\atest" }';

try {
  console.log('str1:', JSON.parse(str1));
} catch (e) {
  console.log('str1 fail')
}

try {
  console.log('str2:', JSON.parse(str2))
} catch (e) {
  console.log('str2 fail')
}

str1将成功解析为所需的{ test: 'path\test' }格式
str2将失败。

似乎只有在\\之后的字符是valid JavaScript escape characters之一时,此命令才能成功

(\ t:在str1情况下为水平制表符)

预期的行为是将\\转义为单个\

此行为是否有解释?我们很困惑,不胜感激!

1 个答案:

答案 0 :(得分:3)

当您的字符串文字带有两个反斜杠时,这两个反斜杠将被解释为单个文字反斜杠,例如,.length的{​​{1}}为5,而不是6。

'\\test'仅允许在转义 的字符之前使用反斜杠,例如JSON.parse(水平标签)和t(换行符)。当您在无法转义的字符(例如n)前加一个文字反斜杠时,a会引发错误。 (这与Javascript字符串文字不同,Javascript字符串文字可以不必要地转义了常规字符-例如JSON.parse等效于const str = '\a',并且不会引发错误。)您可以看到JSON here中允许的内容的图示-如第四幅图所示,在'a'之后,唯一允许的字符是\"\/bfnrt中的一个,每个X是一个十六进制数字。

如果您希望解析对象中的uXXXX属性的值是字符串test,后跟文字反斜杠,后跟pathtest,您在声明字符串文字时需要使用四个反斜杠-首先,使Javascript解释器将其解释为两个文字反斜杠,其次,让atest解释两个文字反斜杠作为已解析字符串中的单个反斜杠。

JSON.parse

您还可以使用const str1 = '{ "test": "path\\\\test" }'; const str2 = '{ "test": "path\\\\atest" }'; try { console.log('str1:', JSON.parse(str1)); } catch (e) { console.log('str1 fail') } try { console.log('str2', JSON.parse(str2)) } catch (e) { console.log('str2 fail') }定义字符串文字,以将字符串中的任何单个反斜杠解释为单个文字反斜杠(而不是转义序列的开头):

String.raw