【问题标题】:Pass a PHP string to a JavaScript variable (and escape newlines) [duplicate]将 PHP 字符串传递给 JavaScript 变量(并转义换行符)[重复]
【发布时间】:2010-09-15 03:44:59
【问题描述】:

对 PHP 字符串进行编码以输出到 JavaScript 变量的最简单方法是什么?

我有一个包含引号和换行符的 PHP 字符串。我需要将此字符串的内容放入 JavaScript 变量中。

通常,我会在 PHP 文件中构建我的 JavaScript,就像这样:

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

但是,当$myVarValue 包含引号或换行符时,这不起作用。

【问题讨论】:

  • 只是想指出您可以在将字符串传递给json_encode 之前使用utf8_encode()。这就是我正在做的事情:echo json_encode(utf8_encode($msg));
  • 不是stackoverflow.com/questions/23740548/… 的副本。后者谈到 AJAX 等和网络问题,而这里是关于编码/转义/引号和换行符。让我们重新开始? (顺便说一句,这里接受的内容很短,效果很好并且有数百票)

标签: php javascript escaping newline


【解决方案1】:

扩展其他人的答案:

<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 会转义正斜杠,因此即使是包含&lt;/script&gt; 的字符串也会被安全转义以使用脚本块进行打印。

【讨论】:

  • 如果您使用 UTF-8,那是迄今为止最好的解决方案。
  • 重要的是 json_encode 的实现转义了正斜杠。如果没有,如果 $myVarValue 是“”,这将不起作用。但是 json_encode 确实会转义正斜杠,所以我们很好。
  • 如果你不是 5.2,试试 jsonwrapper from botell.com boutell.com/scripts/jsonwrapper.html
  • 请注意,如果你在onclick属性等中使用它,你需要将json_encode的结果传递给htmlspecialchars,如下所示:htmlspecialchars(json_encode($string),ENT_QUOTES,'utf-8')否则你可以遇到问题,例如,foo()&amp;&amp;bar; 中的 &amp;bar; 被解释为 HTML 实体。
  • @hakre:但是 PHP 字符串如何包含 "...&lt;/script&gt;..." 可以成为 JS 非字符串 &lt;/script&gt; 而不仅仅是 JS 字符串 "...&lt;/script&gt;..." 在 PHP 的 json_encode 之后?它总是为字符串添加引号。所以,var x = "...&lt;/script&gt;..."; 只是一个 JS 字符串。没有休息。
【解决方案2】:

偏执版:Escaping every single character

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 作为参数,那么这似乎是最好的方法。
  • @kristoffer-ryhl 正确指出 dechex 不适用于 '\t' (= '\x08'),因此我对其进行了编辑以使用 sprintf。但是,这似乎仍然不适用于 UTF-8 字符(这需要使用 '\u' 代替)...
  • 对于 HTML 属性,您可以使用 &lt;div onclick="alert(&lt;?php echo htmlspecialchars(json_encode($var));?&gt;" /&gt;
  • 这不是 unicode 保存,请查看:docs.laminas.dev/laminas-escaper/escaping-javascript
【解决方案3】:

如果您使用模板引擎来构建您的 HTML,那么您可以随心所欲地填充它!

查看XTemplates。 这是一个不错的、开源的、轻量级的模板引擎。

你的 HTML/JS 看起来像这样:

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

【讨论】:

    【解决方案4】:
    1. 不要。使用 Ajax,将其放在 HTML 中的 data-* 属性中,或者其他有意义的东西中。使用内联脚本会让你的页面更大,could be insecure or still allow users to ruin layout,除非……

    2. …你做了一个更安全的函数:

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

    【讨论】:

    • 我很确定 &lt;!-- 不需要在脚本块中转义,在有效的 Javascript 字符串文字中唯一需要注意的是 &lt;/script&gt;,并且json_encode 永远不会输出它,因为它会转义正斜杠。
    • @Flimm:你看过键盘链接了吗?试试&lt;script&gt;console.log("&lt;!--&lt;script&gt;")&lt;/script&gt;&lt;script&gt;console.log(")/;alert('execute arbitrary code here');&lt;!----&gt;")&lt;/script&gt;,其中传递给console.log 的两个字符串是用户提供的(即模板看起来像&lt;script&gt;console.log({{ s1 }})&lt;/script&gt;&lt;script&gt;console.log({{ s2 }})&lt;/script&gt;,其中$s1$s2 来自错误的JSON 编码器)。当然,第二个字符串包含一个未转义的正斜杠,并且该示例完全是人为的,但是恶意用户仍然可能导致这样的语法错误。
    • @Flimm:这是如何工作的:&lt;!--&lt;script&gt; 导致合法的&lt;/script&gt; 被视为代码而不是结束标记。
    【解决方案5】:

    尽管addslashes(),但不要运行它;如果您在 HTML 页面的上下文中,HTML 解析器仍然可以看到 &lt;/script&gt; 标记,甚至是中间字符串,并假设它是 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 '&lt;' 仅当我引用外部 .js 文件时,它是 inilne ,它工作正常。想法?
    • @RADMKT 只是猜测,但如果它是一个 .js 文件,它可能没有使用 PHP。可能值得在 Web 浏览器中加载外部 JS 文件以查看代码输出。
    【解决方案6】:
    <script>
    var myVar = <?php echo json_encode($myVarValue); ?>;
    </script>
    

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

    【讨论】:

    • 您不能将编码值括在引号中。
    • 请注意,json_encode 会转义正斜杠,这意味着它永远不会意外打印&lt;/script&gt;
    【解决方案7】:

    以下 Micah 的解决方案对我有用,因为我必须自定义的网站不是 UTF-8,所以我不能使用 json;我会投票,但我的代表不够高。

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

    【讨论】:

    • 我也是!这两行代码是 php 发生的最好的事情(至少恕我直言)。非常感谢!!
    【解决方案8】:

    我不确定这是否是不好的做法,但我和我的团队一直在使用混合的 html、JS 和 php 解决方案。我们从想要拉入 JS 变量的 PHP 字符串开始,我们称之为:

    $someString
    

    接下来我们使用页面内隐藏的表单元素,并将它们的值设置为字符串:

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

    那么通过document.getElementById定义一个JS var就很简单了:

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

    现在您可以在任何想要获取 PHP 字符串值的地方使用 JS 变量“moonUnitAlpha”。 这对我们来说似乎非常有效。我们会看看它是否能承受大量使用。

    【讨论】:

    • 我在以前的项目中一直在这样做。下次我会尝试使用jQuery数据。
    • 记得对你的 $someString...他们可以直接使用 javascript: 协议,该协议不受 html 编码值的保护。
    • 为了安全起见,你真的应该这样做value="&lt;?php echo htmlspecialchars(json_encode($someString));?&gt;"
    【解决方案9】:

    我遇到过类似的问题,了解以下是最佳解决方案:

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

    但是,micahwittman 发布的link 表明存在一些细微的编码差异。 PHP 的 rawurlencode() 函数应该符合 RFC 1738,而 Javascript 的 decodeURIComponent() 似乎没有这样的努力。

    【讨论】:

    • decodeURIComponent 符合 RFC 3986,我相信。
    • 这是解析大字符串时的正确解决方案(例如:html 内容为字符串)
    • @RaduGheorghies 为什么?
    【解决方案10】:

    你可以试试

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

    【讨论】:

    • 不完全有效。试试这个字符串::: 我想知道 "hey jude" 因为 1 + 1
    • unescape 现在已弃用。请改用decodeURIComponent
    【解决方案11】:

    您可以将其插入隐藏的 DIV,然后将 DIV 的 innerHTML 分配给您的 JavaScript 变量。你不必担心逃避任何事情。请确保不要将损坏的 HTML 放在那里。

    【讨论】:

    • “不要把损坏的 HTML 放在那里”,这意味着转义 'HTML 实体'(至少是 '
    • 不,只是不要过早关闭你的容器 DIV。
    【解决方案12】:
    function escapeJavaScriptText($string)
    {
        return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\")));
    }
    

    【讨论】:

    • 我需要这个,因为我将变量的内容用作连接的 javascript 表达式的一部分。
    • 这对我很有帮助。
    【解决方案13】:

    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 时,这才是正确的解决方案,其中像 & 这样的字符串标记有意义。否则,最好不要将它们转换为实体。
    【解决方案14】:

    用 JSON 编码

    【讨论】:

    • 这可能是让它 100% 工作的最简单方法。其他情况太多了。
    • Json 仅适用于 UTF-8 字符集。因此,如果您的网站使用非 UTF-8 编码,这不是一个解决方案
    • @nir:一方面,我不知道使用任何其他编码的任何理由,另一方面,完整的 JSON 编码器还可以管理任何需要的字符集转换
    • 使用 JSON 编码是不够的,您还必须确保正确处理任何包含 &lt;/script&gt;(不区分大小写)的 Javascript 字符串。
    • 使用 JSON 编码单个标量值不会将其强制为对象 - 您只需获得一个 utf-8 字符串。例如,假设您的 php 代码如下所示: $x="";你的 HTML 看起来像这样: 浏览的结果是: 注意双引号和转义的斜杠。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多