Что ограничивает этот анализ JSON и что я могу сделать, чтобы это исправить?

Проблема проста для понимания и демонстрации.

Этот код работает нормально:

<?php
    $title = array("dfg","sdfsdg","asfas","Sdfh","Ssdth","Csdgo");
    $title_json = json_encode($title);
?>
<script>
    var obj = JSON.parse('<?= $title_json; ?>');
    console.log(obj);
</script>

Этот код не:

<?php
    $title = array("Is President Trump still using his old Android phone?","Trump sets a dizzying WH pace in first days","Trumps White House Charm Offensive a Contrast to Solitary Obama","The inside story of a basketball teen so tall, he doesn't look real","Scientists say they are closer to making Star Wars holograms","Sperm theft lawsuit leaves appeals court weighing how much a life is worth","Call it Smunday: Heinz pushing to make Super Bowl Monday a national holiday");
    $title_json = json_encode($title);
?>
<script>
    var obj = JSON.parse('<?= $title_json; ?>');
    console.log(obj);
</script>

Выводит ошибку в консоли: Uncaught SyntaxError: missing ) after argument list - (index):20, где строка 20 - это строка с JSON.parse, и если вы посмотрите на исходный код страницы, строка гласит:

var obj = JSON.parse('["Is President Trump still using his old Android phone?","Trump sets a dizzying WH pace in first days","Trump's White House Charm Offensive a Contrast to Solitary Obama","The inside story of a basketball teen so tall, he doesn't look real","Scientists say they are closer to making 'Star Wars' holograms","Sperm theft lawsuit leaves appeals court weighing how much a life is worth","Call it 'Smunday': Heinz pushing to make Super Bowl Monday a national holiday"]');

Вы можете заметить, что два примера кода совершенно одинаковы, массивы даже имеют одинаковую длину, единственное отличие состоит в том, что во втором примере строки длиннее. Означает ли это, что существует максимальная длина строк, которые могут быть проанализированы JSON?


person Mark Kramer    schedule 21.02.2017    source источник
comment
Обратите внимание, что там, где вы показали строку, как она видна в браузере, цветовая подсветка синтаксиса, добавленная SO в ваш код, намекает на проблему.   -  person nnnnnn    schedule 21.02.2017
comment
В наши дни вы можете использовать ` (также известные как обратные кавычки) для переноса строк. (т.е. var obj = JSON.parse(`["Is Pre..."]`);   -  person haxxxton    schedule 21.02.2017
comment
@nnnnnn Действительно, если бы среда IDE, которую я использовал, разделяла эту подсветку, мне, вероятно, никогда не пришлось бы задавать этот вопрос, я бы знал, что это апострофы. Конечно, я все еще не знал, что мне даже не нужен JSON.parse, и потратил бы некоторое время, пытаясь понять, как избежать апострофов.   -  person Mark Kramer    schedule 21.02.2017
comment
Однако будьте осторожны, эти ответы без кавычек предполагают, что никогда не бывает случаев, когда ваш json_encode сбой молча (скажем, из-за того, что были предоставлены неверные данные). так как это приведет к тому, что js на лицевой стороне будет выглядеть как var obj = ;, что вызовет Uncaught SyntaxError: Unexpected token ;   -  person haxxxton    schedule 21.02.2017
comment
Массив заполняется из базы данных, которая сама заполняется записями в форме, поэтому, если я правильно настроил проверку формы, не должно быть неверных данных.   -  person Mark Kramer    schedule 21.02.2017
comment
@MarkKramer, согласен, просто предупреждение в случае, если вы пытаетесь делать такие вещи, как json_encode такие вещи, как искаженные символы UTF-8 (см. этот пример)   -  person haxxxton    schedule 21.02.2017


Ответы (1)


Ваши данные JSON содержат '. Поэтому, если вы введете эти данные в строковый литерал с разделителями ', этот строковый литерал будет закрыт преждевременно и вызовет синтаксическую ошибку. Простой пример:

var foo = '{"key": "This key's value"}';

Вы должны заметить это, если посмотрите на сгенерированный исходный код JavaScript.

Здесь нет необходимости использовать JSON.parse. Внедренный JSON можно интерпретировать как литерал объекта/массива JavaScript:

var obj = <?= $title_json; ?>;

См. также: Как передать переменные и данные из PHP в JavaScript?

person Felix Kling    schedule 21.02.2017
comment
Тогда при каких обстоятельствах мне понадобится JSON.parse, я просто следил за статьей, в которой говорилось, что именно так вы передаете массивы PHP в javascript. - person Mark Kramer; 21.02.2017
comment
Вам нужно JSON.parse, если у вас есть строковое значение, содержащее JSON. Это произойдет, например, если вы сделаете XMLHTTPRequest и получите JSON в качестве ответа. Но здесь вы генерируете исходный код JavaScript из PHP. Поскольку JSON может быть проанализирован как исходный код JavaScript (если он находится в правильном месте), вы можете напрямую внедрить его в источник как объект/массив вместо того, чтобы вводить его как содержимое строкового литерала. Как вы заметили, это чревато ошибками, поскольку определенные символы и последовательности символов имеют разное значение внутри строкового литерала. - person Felix Kling; 21.02.2017
comment
Возможно, это немного надуманно, но рассмотрим следующий пример: если бы у вас было просто числовое значение, вы, вероятно, сделали бы var n = <= 42;>; вместо var n = eval('<= 42;>');. eval не нужен, потому что 42 является допустимым числовым литералом в JS (где этот пример не соответствует действительности, так это то, что eval в любом случае не будет работать, если это не действительный код JS, а ¯\_(ツ)_/¯). - person Felix Kling; 21.02.2017