Передайте строку PHP в переменную JavaScript (и экранируйте символы новой строки)

Как проще всего закодировать строку PHP для вывода в переменную JavaScript?

У меня есть строка PHP, которая включает кавычки и новые строки. Мне нужно, чтобы содержимое этой строки было помещено в переменную JavaScript.

Обычно я просто создаю свой JavaScript в файле PHP, а ля:

<script>
  var myvar = "<?php echo $myVarValue;?>";
</script>

Однако это не работает, если $myVarValue содержит кавычки или символы новой строки.

Просто хотел указать, что вы можете использовать utf8_encode() перед передачей строки в json_encode. Вот что я делаю: echo json_encode(utf8_encode($msg));

carlosvini 11.09.2013 22:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
384
1
321 974
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

закодируйте его с помощью JSON

Вероятно, самый простой способ заставить это работать 100% времени. Слишком много случаев, чтобы рассматривать их иначе.

willasaywhat 03.10.2008 22:42

Json работает только с кодировкой UTF-8. Так что это не решение, если ваш сайт работает в кодировке, отличной от UTF-8.

Nir 27.04.2009 16:06

@nir: с одной стороны, я не знаю причин использовать любую другую кодировку, с другой стороны, полный кодировщик JSON также управляет любым необходимым преобразованием кодировки

Javier 28.04.2009 06:03

Кодирования с помощью JSON недостаточно, вы также должны убедиться, что любая строка Javascript, содержащая </script> (без учета регистра), обрабатывается правильно.

Flimm 13.11.2015 18:03

Единственное, что меня беспокоит, так это то, что кодирование с помощью json заставит его преобразовать в объект. На практике это легче понять, но когда вы дойдете до сложных массивов данных, в частности, для чтения результатов SQL из базы данных, программисту потребуется более глубокое знание javascript для эффективной обработки данных. По сути, я говорю, что пример сценария использования был бы отличным.

Christopher 'Solidus' DeJong 11.07.2016 20:41

Кодирование одного скалярного значения с помощью JSON не приведет к принудительному преобразованию его к объекту - вы просто получите строку utf-8. Например, ваш php-код выглядит так: $ x = "<script> alert ('xss!'); </script>"; и ваш HTML-код выглядит так: <script> var x = <? = json_encode ($ x);?> </script> результат при просмотре будет: <script> var x = "<script> alert ('xss ! '); <\ / script> "</script> Обратите внимание на двойные кавычки и экранированную косую черту.

Craig Jacobs 08.01.2017 00:20

Если вы используете шаблонизатор для создания своего HTML-кода, вы можете заполнить его чем угодно!

Проверьте XTemplates. Это приятный, легкий, шаблонный движок с открытым исходным кодом.

Ваш HTML / JS будет выглядеть так:

<script>
    var myvar = {$MyVarValue};
</script>

htmlspecialchars

Описание

string htmlspecialchars ( string $string [, int $quote_style [, string $charset [, bool $double_encode ]]] )

Некоторые символы имеют особое значение в HTML и должны быть представлены объектами HTML, если они хотят сохранить свое значение. Эта функция возвращает строку с некоторыми из этих преобразований; сделанные переводы наиболее полезны для повседневного веб-программирования. Если вам нужно перевести все символы HTML, используйте вместо этого htmlentities ().

Эта функция полезна для предотвращения того, чтобы вводимый пользователем текст содержал разметку HTML, например, в доске сообщений или в приложении гостевой книги.

Выполненные переводы:

* '&' (ampersand) becomes '&amp;'
* '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set.
* ''' (single quote) becomes '&#039;' only when ENT_QUOTES is set.
* '<' (less than) becomes '&lt;'
* '>' (greater than) becomes '&gt;'

http://ca.php.net/htmlspecialchars

Это будет правильным решением только в том случае, если содержимое переменной JS действительно должно быть HTML, где строковый токен, например & amp; имеет значение. В противном случае лучше не преобразовывать их в сущности.

Peter Bailey 03.10.2008 22:48

function escapeJavaScriptText($string)
{
    return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\")));
}

Мне это было нужно, потому что я использовал содержимое переменной как часть конкатенированного выражения javascript.

Phil Cairns 22.02.2018 23:27

Это мне действительно помогло.

Austin 17.02.2019 06:37

Вы можете вставить его в скрытый DIV, а затем назначить innerHTML DIV вашей переменной JavaScript. Вам не нужно беспокоиться о том, чтобы от чего-либо сбежать Только убедитесь, что не поместили туда сломанный HTML.

"не помещать туда сломанный HTML", это означает экранирование "сущностей HTML" (по крайней мере, "<" и "&")

Javier 18.02.2009 06:55

Нет, просто не закрывайте контейнер DIV раньше времени.

Diodeus - James MacFarlane 19.02.2009 00:30

Вы могли бы попробовать

<script type = "text/javascript">
    myvar = unescape('<?=rawurlencode($myvar)?>');
</script>

Не работает полностью. Попробуйте с этой строкой ::: Мне интересно "эй, джуд", потому что 1 + 1 <5 ::: мы все еще получаем & lt; так что не 100% двунаправленная транслитерация

Tom Auger 23.12.2010 01:55

unescape устарел. Вместо этого используйте decodeURIComponent.

emix 19.05.2016 14:05
Ответ принят как подходящий

Расширяя чужой ответ:

<script>
  var myvar = <?php echo json_encode($myVarValue); ?>;
</script>

Для использования json_encode () требуется:

  • PHP 5.2.0 или выше
  • $myVarValue в кодировке UTF-8 (или, конечно, US-ASCII)

Поскольку UTF-8 поддерживает полный Unicode, преобразование на лету должно быть безопасным.

Обратите внимание: поскольку json_encode избегает косых черт, даже строка, содержащая </script>, будет безопасно экранирована для печати с блоком сценария.

Если вы используете UTF-8, это, безусловно, лучшее решение.

Kornel 14.10.2008 03:02

Важно, чтобы при реализации json_encode не использовалась косая черта. В противном случае это не сработало бы, если бы $ myVarValue был "</script>". Но json_encode избегает косых черт, так что все в порядке.

Drew LeSueur 01.10.2010 23:40

Если вы не 5.2, попробуйте jsonwrapper с сайта boutell.com boutell.com/scripts/jsonwrapper.html

Tom Auger 23.12.2010 01:57

Если вы используете это в переносимом (например, библиотечном) коде, есть одно предостережение. json_encode () был сообщается как сломанный. У меня это исправлено (5.4.4-7 в debian), но я не знаю о более ранних версиях.

sourcejedi 05.11.2012 16:49

Имейте в виду, что в PHP 5.3 теперь есть опции для экранирования различных символов. См. Пример № 2 для различных выходов: php.net/manual/en/function.json-encode.php

Dan 14.03.2013 03:19

Обратите внимание, что если вы используете это в атрибутах onclick и т. П., Вам необходимо передать результат json_encode в htmlspecialchars, например: htmlspecialchars(json_encode($string),ENT_QUOTES,'utf-8'), иначе у вас могут возникнуть проблемы, например, с &bar; в foo()&&bar;, который интерпретируется как объект HTML. .

user2428118 02.06.2014 18:09

Сработало большое спасибо! Также, чтобы другие не столкнулись с тем же, что и я, при использовании этого: убедитесь, что вы удалили кавычки вокруг переменных json_encoded php, которые вы вставляете в javascript, потому что json_encode уже включает их.

Kt Mack 09.09.2014 07:33

Если строка содержит новую строку, я думаю, она выдаст ошибку

Abhisek Malakar 06.08.2015 11:20

Простой вызов json_encode () для экранирования вывода небезопасен. Добавление JSON_HEX_QUOT | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_TAG в качестве второго параметра помогает в некоторых случаях, но он все же позволяет вам вводить некоторый код JS, например «1; alert (10)» или что-то более опасное в примере, подобном этому. Помимо правильной проверки ввода, я не уверен, что может помочь в этом случае. Без второго параметра внедрение любого кода тривиально.

lucian303 30.12.2015 22:34

Я считаю, что в PHP 5.4+ лучше всего использовать два хороших специальных флага. И, конечно же, короткий синтаксис. Вот он: var myvar = <?=json_encode($myVarValue, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)?>;. Первый говорит не кодировать косую черту /, второй печатает любые символы utf8 не как xNNNN, а как есть.

FlameStorm 20.03.2017 12:45

@FlameStorm: кодирует косую черту, что полезно для предотвращения инъекций </script> (!!), поскольку они становятся </script>. В противном случае тег скрипта закрывается преждевременно, что может быть использовано как часть атаки. - см. также предыдущий комментарий stackoverflow.com/questions/168214/…

hakre 19.05.2017 10:57

@hakre: Но как строка PHP, содержащая "...</script>...", может стать нестроковой JS </script> вместо просто строки JS "...</script>..." после json_encode PHP? Он всегда добавляет кавычки для строки. Итак, var x = "...</script>..."; - это просто строка JS. Без перерыва.

FlameStorm 27.07.2017 17:21

Для тех, кто использует Laravel, вы можете использовать ультра-простой @json($myVarValue). См. «Отрисовка JSON» в разделе laravel.com/docs/5.6/blade#displaying-data.

Ryan DuVal 28.06.2018 20:51

Есть крайние случаи, когда json_encode () недостаточно: docs.zendframework.com/zend-escaper/escaping-javascript

pako 24.10.2018 13:55

привет, пожалуйста, кто-нибудь знает, почему я получаю SyntaxError: expected expression, got '<' при использовании var a = <?php echo json_encode($_REQUEST["errors"]); ?>;, спасибо

Scaramouche 14.03.2019 16:56

У меня была аналогичная проблема, и я понимаю, что следующее - лучшее решение:

<script>
    var myvar = decodeURIComponent("<?php echo rawurlencode($myVarValue); ?>");
</script>

Однако связь, опубликованный micahwittman, предполагает, что есть некоторые незначительные различия в кодировке. Предполагается, что функция PHP rawurlencode() соответствует RFC 1738, в то время как, похоже, не было таких усилий с decodeURIComponent() Javascript.

Я считаю, что decodeURIComponent соответствует RFC 3986.

Ry- 06.06.2014 19:52

Это правильное решение, когда вы разбираете большие строки (например, содержимое html как строку)

Radu Gheorghies 23.09.2015 10:58

@RaduGheorghies Почему?

Tuesdave 27.09.2016 21:39

Приведенное ниже решение Micah сработало для меня, поскольку сайт, который мне пришлось настраивать, не был в UTF-8, поэтому я не мог использовать json; Я бы проголосовал за это, но моя репутация недостаточно высока.

function escapeJavaScriptText($string) 
{ 
    return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\"))); 
} 

Я тоже! Эти две строки кода - лучшее, что случилось с php (по крайней мере, IMHO). Большое спасибо!!

rizalp1 26.10.2012 07:44

Я не уверен, что это плохая практика или нет, но моя команда и я использовали смешанное решение html, JS и php. Мы начинаем со строки PHP, которую хотим вставить в переменную JS, давайте назовем ее:

$someString

Затем мы используем скрытые элементы формы на странице и устанавливаем их значение в виде строки:

<form id = "pagePhpVars" method = "post">
<input type = "hidden" name = "phpString1" id = "phpString1" value = "'.$someString.'" />
</form>

Тогда это простой вопрос определения JS var через document.getElementById:

<script type = "text/javascript" charset = "UTF-8">
    var moonUnitAlpha = document.getElementById('phpString1').value;
</script>

Теперь вы можете использовать переменную JS "moonUnitAlpha" везде, где хотите получить это строковое значение PHP. Похоже, это действительно хорошо работает для нас. Посмотрим, выдержит ли он интенсивное использование.

Я делал это в своих предыдущих проектах. В следующий раз я попробую использовать данные jQuery.

wenbert 27.08.2010 10:05

не забудьте htmlencode ваш $ someString ... и хотя это нормально для input @ value, вы должны быть особенно осторожны с атрибутами типа href / src / onclick (попробуйте белый список), так как они могут сразу перейти к использованию javascript : протокол, от которого не защищены значения в кодировке html.

Craig Francis 19.10.2012 13:55

На всякий случай вам действительно стоит сделать value = "<?php echo htmlspecialchars(json_encode($someString));?>".

Flimm 13.11.2015 18:02

Параноидальная версия: Экранирование каждого символа.

function javascript_escape($str) {
  $new_str = '';

  $str_len = strlen($str);
  for($i = 0; $i < $str_len; $i++) {
    $new_str .= '\x' . sprintf('%02x', ord(substr($str, $i, 1)));
  }

  return $new_str;
}

Обновлено: Причина, по которой json_encode() может не подходить, заключается в том, что иногда вам нужно предотвратить создание ", например

<div onclick = "alert(???)" />

У меня сработало экранирование каждого персонажа. json_encode не очень хорошо обрабатывает обратную косую черту. Если вам нужно передать что-то вроде регулярного выражения из mysql в javascript в качестве параметра, то это лучший способ.

Ekim 22.05.2012 08:05

@ kristoffer-ryhl правильно отмечает, что dechex не работает для '\ t' (= '\ x08'), поэтому я отредактировал его, чтобы использовать sprintf. Однако это все еще не работает для символов UTF-8 (вместо этого потребуется использовать '\ u') ...

giraff 08.11.2015 15:47

Для атрибута HTML вы можете сделать <div onclick = "alert(<?php echo htmlspecialchars(json_encode($var));?>" />

Flimm 13.11.2015 17:55

Это не сохранение в Юникоде, проверьте это: docs.laminas.dev/laminas-escaper/escaping-javascript

vinsa 28.05.2020 19:46

Не запускайте его через addslashes(); если вы находитесь в контексте HTML-страницы, анализатор HTML все еще может видеть тег </script>, даже в середине строки, и предполагать, что это конец JavaScript:

<?php
    $value = 'XXX</script><script>alert(document.cookie);</script>';
?>

<script type = "text/javascript">
    var foo = <?= json_encode($value) ?>; // Use this
    var foo = '<?= addslashes($value) ?>'; // Avoid, allows XSS!
</script>

Возможно, я делаю глупую ошибку, но когда я пытаюсь выполнить этот код, я получаю следующую консольную ошибку SyntaxError: expected expression, got '<' ТОЛЬКО, когда я ссылаюсь на внешний файл .js, когда он inilne, он работает нормально. Мысли?

Ryan Dorn 13.08.2015 17:52

@RADMKT Просто предположение, но если это файл .js, он, вероятно, не использует PHP. Возможно, стоит загрузить внешний файл JS в веб-браузере, чтобы увидеть вывод кода.

Craig Francis 13.08.2015 17:55

<script>
var myVar = <?php echo json_encode($myVarValue); ?>;
</script>

или же

<script>
var myVar = <?= json_encode($myVarValue) ?>;
</script>

Вы не должны заключать закодированное значение в кавычки.

Salman A 25.01.2013 18:47

Обратите внимание, что json_encode избегает косых черт, что означает, что он никогда не напечатает </script> случайно.

Flimm 13.11.2015 18:01
  1. Не надо. Используйте Ajax, поместите его в атрибуты data-* вашего HTML или что-нибудь еще значимое. Использование встроенных скриптов увеличивает размер ваших страниц и может быть небезопасным или по-прежнему позволять пользователям испортить макет, если…

  2. … Вы делаете более безопасную функцию:

    function inline_json_encode($obj) {
        return str_replace('<!--', '<\!--', json_encode($obj));
    }
    

Я почти уверен, что <!-- не нужно экранировать в блоке сценария, единственное, на что вам нужно обратить внимание в допустимом строковом литерале Javascript, - это </script>, а json_encode никогда не выводит это, потому что он избегает косых черт.

Flimm 13.11.2015 18:00

@Flimm: Вы смотрели ссылку на кодовую панель? Попробуйте <script>console.info("<!--<script>")</script><script>console.‌​log(")/;alert('execu‌​te arbitrary code here');<!---->")</script>, где две строки, переданные в console.info, предоставляются пользователем (т. Е. Шаблон выглядит как <script>console.info({{ s1 }})</script><script>console.info({{ s2 }})</script>, где $s1 и $s2 поступают из плохого кодировщика JSON). Конечно, вторая строка содержит неэкранированную косую черту, и пример полностью надуманный, но злоумышленник все равно может вызвать синтаксическую ошибку, подобную этой.

Ry- 13.11.2015 23:58

@Flimm: Как это работает: <!--<script> заставляет законный </script> обрабатываться как код, а не как конечный тег.

Ry- 13.11.2015 23:59

Другие вопросы по теме