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

339

Что является самым простым способом кодирования строки PHP для вывода в переменную JavaScript?

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

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

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

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

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

14 ответов

492
Лучший ответ

Расширение ответа на кого-то другого:

<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>, будет безопасно удалена для печати с блоком script.

  • 10
    Если вы используете UTF-8, это лучшее решение на сегодняшний день.
  • 4
    Важно, чтобы реализация json_encode избегала прямой косой черты. Если бы это не так, это не сработало бы, если бы $ myVarValue был "</ script>". Но json_encode избегает косой черты, так что мы в порядке.
Показать ещё 13 комментариев
26

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

  • 0
    Вероятно, самый простой способ заставить это работать 100% времени. Слишком много дел, чтобы покрыть иначе.
  • 0
    Json работает только с UTF-8 Charset. Так что это не решение, если ваш сайт работает в кодировке не-UTF-8
Показать ещё 4 комментария
19
function escapeJavaScriptText($string)
{
    return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\")));
}
  • 0
    Я нуждался в этом, потому что я использовал содержимое переменной как часть составного выражения javascript.
  • 0
    Это действительно помогло мне.
17

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

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

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

  • 0
    Я полагаю, что decodeURIComponent соответствует RFC 3986.
  • 0
    Это правильное решение, когда вы анализируете большие строки (например, HTML-содержимое в виде строки)
Показать ещё 1 комментарий
9

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

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;
}

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

<div onclick="alert(???)" />
  • 0
    Спасение каждого персонажа работало на меня. json_encode не очень хорошо обрабатывает обратную косую черту. Если вам нужно передать что-то вроде регулярного выражения из mysql в javascript в качестве параметра, то это лучший способ.
  • 0
    @ kristoffer-ryhl правильно отмечает, что dechex не работает для '\ t' (= '\ x08'), поэтому я отредактировал его для использования sprintf. Тем не менее, это все еще не работает для символов UTF-8 (вместо этого потребуется использовать «\ u») ...
Показать ещё 1 комментарий
5
<script>
var myVar = <?php echo json_encode($myVarValue); ?>;
</script>

или

<script>
var myVar = <?= json_encode($myVarValue) ?>;
</script>
  • 1
    Вы не должны заключать закодированное значение в кавычки.
  • 0
    Обратите внимание, что json_encode экранирует косые черты, что означает, что он никогда не будет напечатан </script> случайно.
3

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

function escapeJavaScriptText($string) 
{ 
    return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\"))); 
} 
  • 0
    Я тоже! Эти две строки кода - лучшее, что случилось с php (по крайней мере, ИМХО). Большое спасибо!!
2
  • 0
    Я почти уверен, что <!-- не нужно экранировать внутри блока скрипта, единственное, на что нужно обратить внимание в допустимом строковом литерале Javascript - это </script> , и json_encode никогда не выводит его, потому что он ускользает от косой черты.
  • 0
    @Flimm: Вы смотрели на ссылку на кодовую панель? Попробуйте <script>console.log("<!--<script>")</script><script>console.log(")/;alert('execute arbitrary code here');<!---->")</script> , где две строки, переданные в console.log предоставляются пользователем (т. е. шаблон выглядит как <script>console.log({{ s1 }})</script><script>console.log({{ s2 }})</script> , где $s1 и $s2 получены из плохого кодера JSON). Конечно, вторая строка содержит косую черту без экранирования, и пример полностью придуман, но злонамеренный пользователь все еще может вызвать синтаксическую ошибку, подобную этой.
Показать ещё 1 комментарий
2

Не запускайте его, хотя 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>
  • 0
    Возможно, я делаю глупую ошибку, но когда я пытаюсь выполнить этот код, я получаю следующую консольную ошибку SyntaxError: expected expression, got '<' ТОЛЬКО SyntaxError: expected expression, got '<' когда я обращаюсь к внешнему файлу .js, когда он inilne, он работает отлично. Мысли?
  • 0
    @RADMKT Просто предположение, но если это файл .js, он, вероятно, не использует PHP. Возможно, стоит загрузить внешний файл JS в веб-браузер, чтобы увидеть вывод кода.
2

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

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

Вы можете попробовать

<script type="text/javascript">
    myvar = unescape('<?=rawurlencode($myvar)?>');
</script>
  • 0
    Не работает полностью Попробуйте с этой строкой ::: Мне интересно "Эй, Джуд", потому что 1 + 1 <5 ::: мы все еще получаем & lt; так что не 100% двунаправленная транслитерация
  • 0
    unescape устарела. decodeURIComponent этого используйте decodeURIComponent .
2

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

  • 0
    «не помещать туда поврежденный HTML», что означает экранирование «сущностей HTML» (как минимум «<» и «&»)
  • 0
    Нет, просто не закрывайте контейнер DIV преждевременно.
-1

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

Отъезд XTemplates. Это хороший, с открытым исходным кодом, легкий, шаблонный движок.

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

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

Я не уверен, что это плохая практика или нет, но моя команда и я используем смешанное решение 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. Кажется, это работает очень хорошо для нас. Мы посмотрим, будет ли это зависеть от тяжелого использования.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню