带双引号的json解析错误

时间:2009-06-04 09:58:22

标签: php javascript json parsing double-quotes

即使转义为双引号也会引发解析错误 看下面的代码

//parse the json in javascript  
var testJson = '{"result": ["lunch", "\"Show\""] }';  
var tags = JSON.parse(testJson);  
alert (tags.result[1]);

由于双引号(已经转义),这会抛出解析错误 即使eval()也不会在这里工作 但如果我用这样的双斜线逃脱它:

var result = '{"result": ["lunch", "\\"Show\\""] }';  
var tags = JSON.parse(result);  
alert (tags.result[1]);

然后它运作正常。
为什么我们需要在javascript中使用双斜杠? 问题是PHP json_encode()函数使用单个斜杠(例如:\"show\")转义双引号,而JSON.parse将无法解析。我该如何处理这种情况?

9 个答案:

答案 0 :(得分:34)

Javascript unescapes它的字符串和json unescapes他们也。 第一个字符串('{"result": ["lunch", "\"Show\""] }')被json解析器看作 {"result": ["lunch", ""Show""] },因为javascript中的\"表示",但不会退出双引号字符串。

第二个字符串'{"result": ["lunch", "\\\"Show\\\""] }'首先转义为{"result": ["lunch", "\"Show\""] }(这是由json正确转义的)。

我认为,'{"result": ["lunch", "\\"Show\\""] }'也应该有用。

答案 1 :(得分:30)

好吧,最后,JSON的解析使用相同的eval,所以当你给他们smth时没有区别。语法不正确。在这种情况下,你必须在php中正确地转义你的引号,然后用json_encode转义它们和它们的转义斜杠

<?php
    $json = '{"result": ["lunch", "\"Show\""] }';
    echo json_encode($json);
?>

OUTPUT: "{\"result\": [\"lunch\", \"\\\"Show\\\"\"] }"

这应该适用于客户端JS(如果我没有拼写错误)。

答案 2 :(得分:11)

这个问题是由双折叠字符串转义机制引起的:一个来自JS,一个来自JSON。

反斜杠字符与另一个后续字符的组合用于表示字符串中无法表示的一个字符。 ''\\''代表'\'等。

这种转义机制发生在JSON.parse()工作之前。

例如,

var parsedObj = JSON.parse('{"sentence": "It is one backslash(\\\\)"}');
console.log(parsedObj.sentence);
>>>"It is one backslash(\)"

从字符串生成器的角度来看,将四个反斜杠'\'传递给JavaScript解释器。

从JavaScript解释器的角度来看,它解释了有两个反斜杠(\),因为每个'\\'序列将被解释为一个'\'。

从JSON解析器的角度来看,接收两个反斜杠(\\),JSON字符串转义规则会将其解析为一个单独的'\',这是输出结果。

首先解释一下代码:

var testJson = '{"result": ["lunch", "\"Show\""] }';
//The real string after sequence escaping in to JS is
//'{"result": ["lunch", ""Show""] }' 
//which is passed into the JSON.parse.
//Thus, it breaks the JSON grammar and generates an error
var tags = JSON.parse(testJson);  
alert (tags.result[1]);

答案 3 :(得分:10)

来自docs

  

JSON_HEX_APOS(整数)全部'转换为\ u0027
  JSON_HEX_QUOT(整数)全部“转换为\ u0022

json_encode()需要两个参数,值和选项。所以试试

json_encode($result, JSON_HEX_QUOT); // or
json_encode($result, JSON_HEX_QUOT | JSON_HEX_APOS);

我没试过这个。

答案 4 :(得分:3)

php.ini 中关闭magic_quotes_gpc

答案 5 :(得分:2)

php到javascript对象(php&gt; = 5.3.0)

var storesLocations = JSON.parse('<?php echo addslashes(json_encode($storesLocations,JSON_HEX_APOS | JSON_HEX_QUOT)) ?>');

答案 6 :(得分:0)

如果添加了标准C转义符,则JSON.parse会将\"等序列转换为"\\转换为\\n进入换行等等。

'foo\\bar\nbaz"' === JSON.parse('"foo\\\\bar\\nbaz\\""')

在我们的项目案例中:

原始字符串""{\"lat\":28.4594965,\"lng\":77.0266383}""

传递给JSON.parse()

"{"lat":28.4594965,"lng":77.0266383}"

On 2 nd 传递给JSON.parse()

{lat: 28.4594965, lng: 77.0266383}

请注意,JSON.parse()删除了转义字符,而不是将string转换为object

删除转义字符后,字符串到对象的转换有效。

以下是演示:

while (typeof p1 != 'object') {
  p1 = JSON.parse(p1);
  pass++;
  console.log('On pass ', pass, p1);
}

答案 7 :(得分:0)

这可能会有所帮助:

<?php
$json = '{"result": ["lunch", "\"Show\""] }';
echo addslashes(json_encode($json));

答案 8 :(得分:0)

尝试一下。然后尝试发表评论

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<pre><?php ($_POST)?print_r($_POST):'' ?></pre>

<form method="POST">
    <input type="text" name="name"><br>
    <input type="email" name="email"><br>
    <input type="time" name="time"><br>
    <input type="date" name="date"><br>
    <input type="hidden" name="id"><br>
    <textarea name="detail"></textarea>
    <input type="submit" value="Submit"><br>
</form>
<?php 
/* data */
$data = [
            'name'=>'vinay"'."'\\\\",
            'email'=>'imvsrajput@demo.demo',
            'time'=>date('H:i:00'),
            'date'=>date('Y-m-d'),
            'detail'=>'Try this var_dump(0=="ZERO") \\ \\"'." ' \\\\    ",
            'id'=>123,
        ];
?>
<span style="display: none;" class="ajax-data"><?=json_encode($data)?></span>
<script type="text/javascript">
    /* Error */
    // var json = JSON.parse('<?=json_encode($data)?>');
    /* Error solved */
    var json = JSON.parse($('.ajax-data').html());
    console.log(json)
    /* automatically assigned value by name attr */
    for(x in json){
        $('[name="'+x+'"]').val(json[x]);
    }
</script>