将 PHP 变量传递给外部 JavaScript(或 jQuery)文件的最有效方法

Posted

技术标签:

【中文标题】将 PHP 变量传递给外部 JavaScript(或 jQuery)文件的最有效方法【英文标题】:Most efficient way to pass PHP variables to external JavaScript (or jQuery) file 【发布时间】:2014-09-11 08:57:36 【问题描述】:

我已经阅读了几篇关于这个问题的帖子,发现this 是最简单的解决方案,这是我的代码:

js PHP内部代码

<script>
    <!--// 
      var jsBaseurl = <?php echo json_encode(BASE_URL."/"); ?>;
      var jsTitle = <?php echo json_encode($h1_title); ?>;
      var jsSubtl = <?php echo json_encode($h2_title);?>;
    //-->
</script>
<script src="external.js"></script>

外部.js

var siteURL=jsBaseurl;
alert(siteURL+jsTitle+jsSubtl)

效果很好,我的问题是关于 Pang 和 biplav 的以下 cmets

警告:这可能会杀死您的网站。示例:

<?php $myVarValue = '<!--<script>'; ?>

详情请见this question。解决方案:使用 JSON_HEX_TAG 转义 (需要 PHP 5.3.0)。 - Pang

这样做的另一个缺点是会影响初始页面加载时间。 - biplav

我想知道 Pang 评论的简单解决方案以及这一切如何影响性能(页面加载时间)。非常感谢!

【问题讨论】:

如果 json_encode() 的输出包含 javascript 中不太可能的非法字符,它会杀死您的网站。 如果你在任何情况下使用PHP,它不会影响页面性能,只要你不把愚蠢的东西放在你自己的PHP中,它就不会坏,但是如果你把愚蠢的东西放在任何PHP 脚本中,你可以杀死你自己的网站。你是网站管理员 @Daniel 这意味着 json_encode() 被破坏并输出非法 JSON,因为没有合法的 JSON 会是非法的 JavaScript。 由于json_encode() 确实产生了一个字符串,我不确定这如何适用于成为一个问题,而不是拥有 Firebug 的用户。 @rsp 对此不是 100% 确定,但感谢您的澄清;) 【参考方案1】:

关于问题1:在json_encode()中使用JSON_HEX_TAG

示例 1 考虑一下这段简单的代码。

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

输出:

<script>
    var myvar = "hello world";
    alert(myvar);
</script>

它会提醒hello world很好。

示例 2 让我们尝试将&lt;/script&gt; 作为字符串。

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

输出:

<script>
    var myvar = "<\/script>";
    alert(myvar);
</script>

它会提醒&lt;/script&gt;很好。

如您所见,斜线 (/) 正确转义为 \/

示例 3 现在,考虑这个非常特殊的字符串:&lt;!--&lt;script&gt;

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

输出:

<script>
    var myvar = "<!--<script>";
    alert(myvar);
</script>

令人惊讶的是,它不会发出任何警报,并且错误控制台中也没有任何内容。 什么?!

如果您检查 JSON 的规范,&lt;!--&lt;script&gt; 中的所有字符都不需要转义,那么出了什么问题?

图片改编自json.org

如需完整且解释清楚的答案,请阅读this amazing Q & A。简而言之,事实证明, &lt;script&gt; 块中的 &lt;!--&lt;script&gt; 会混淆 html 解析器。 PHP 实际上在json_encode() 中正确地完成了它的工作; 你不能在那里有&lt;!--&lt;script&gt;,即使它是一个完全有效的 JavaScript 字符串!

我自己做了一些简单的测试。浏览器实际上会忽略&lt;!--&lt;script&gt; 之后的所有内容,所以如果它发生在页面中间, 整个页面的后半部分消失了!我不确定是否有人真的可以在那里注入恶意的东西,比如说,任意执行 代码,但这已经够糟糕了。

还有,

如果$myVarValue 中不仅有一个字符串,还有像array("key" =&gt; array("one", "and&lt;!--&lt;script&gt;two", 3)) 这样的复杂对象,其中包括&lt;!--&lt;script&gt;,那还是很糟糕。 如果您有一个纯 HTML 文件(即没有 PHP),并且在您的 &lt;script&gt; 块中的任何位置(甚至在 JavaScript 注释中)都有 &lt;!--&lt;script&gt;,那也很糟糕。 如果您使用其他非 PHP 的服务器端编程语言并生成 &lt;!--&lt;script&gt;,那也很糟糕。 如果你的 PHP 是直接输出 JavaScript (Content-type: application/javascript),其实没问题[1]

解决方案?使用JSON_HEX_TAG 转义&lt;&gt;(需要PHP 5.3.0)。

<script>
    <?php $myVarValue = '<!--<script>'; ?>
    var myvar = <?php echo json_encode($myVarValue, JSON_HEX_TAG); ?>;
    //                                            ^^^^^^^^^^^^^^
    alert(myvar);
</script>

输出:

<script>
    var myvar = "\u003C!--\u003Cscript\u003E";
    alert(myvar);
</script>

它会提醒&lt;!--&lt;script&gt;万岁!

之所以有效,是因为输出中不再有&lt;!--&lt;script&gt;,因此不再存在 HTML 解析问题。

注意:如果您打印到&lt;script&gt; 块中,则不需要JSON_HEX_TAG

[1] 在这里,“ok”仅仅意味着它没有&lt;!--&lt;script&gt; 问题。不建议动态生成外部 JavaScript 文件,因为它有很多缺点,例如 here、here、here 中的那些。


关于问题2:初始页面加载时间

实际上,这很明显。如果获取$myVarValue的值所需要的时间较长 (例如,您正在从数据库中获取大量数据),PHP 将不得不等待,浏览器和用户也是如此。 这意味着更长的初始页面加载时间。如果您稍后使用 Ajax 加载数据,它们将没有 等待看到初始结果,但是,Ajax 调用将是一个额外的 HTTP 请求,所以它 意味着更多的服务器工作负载,以及更多的网络负载。

当然,每种方法都有其优点和缺点,因此您必须做出决定。我建议阅读this excellent Q & A。

【讨论】:

@Pang,非常感谢您的时间和详细的示例!由于大多数人不知道这种可能性,我希望它也有助于其他人搜索将 PHP 变量传递到外部 .js 文件。我认为 &lt;!--&lt;script&gt; 的情况很常见,所以问题是真实的。【参考方案2】:

很确定这不会破坏它。 json_encode 的全部意义在于倾倒是安全的。

&lt;/script&gt; 可能会破坏它,但 PHP 默认将 / 转义为 \/,因此您不必担心。

【讨论】:

Niet,Yatko,你能在下面测试一下吗?除非我修改字符串文字,否则这不会发出任何警报。也许这只是我的运气不好,但我在不同的浏览器上进行了测试,甚至在 2 个不同的在线 PHP“提琴手”上测试了运行它。非常感谢。 &lt;script&gt; &lt;?php $myVarValue = '&lt;!--&lt;script&gt;'; ?&gt; var myvar = &lt;?php echo json_encode($myVarValue); ?&gt;; alert(myvar); &lt;/script&gt; Pang 是对的,它确实破坏了代码:var jsTitle = &lt;?php echo json_encode($h1_title."&lt;!--&lt;script&gt;"); ?&gt;; - @Pang,您能否解释一下您对JSON_HEX_TAG 的建议。谢谢!

以上是关于将 PHP 变量传递给外部 JavaScript(或 jQuery)文件的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章

将 PHP 数组传递给外部 jQuery $.ajax

如何将变量从外部 JavaScript 传递到 HTML 表单

将 PHP 变量传递给 Javascript

如何从 Blade 格式 HTML 将 PHP 变量传递给 JavaScript 函数

Laravel 使用 AJAX 将 Javascript 变量传递给 PHP 并检索那些

通过 ajax 将 Javascript 变量传递给 PHP