将 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
让我们尝试将</script>
作为字符串。
<script>
<?php $myVarValue = '</script>'; ?>
var myvar = <?php echo json_encode($myVarValue); ?>;
alert(myvar);
</script>
输出:
<script>
var myvar = "<\/script>";
alert(myvar);
</script>
它会提醒</script>
。 很好。
如您所见,斜线 (/
) 正确转义为 \/
,
示例 3
现在,考虑这个非常特殊的字符串:<!--<script>
<script>
<?php $myVarValue = '<!--<script>'; ?>
var myvar = <?php echo json_encode($myVarValue); ?>;
alert(myvar);
</script>
输出:
<script>
var myvar = "<!--<script>";
alert(myvar);
</script>
令人惊讶的是,它不会发出任何警报,并且错误控制台中也没有任何内容。 什么?!
如果您检查 JSON 的规范,<!--<script>
中的所有字符都不需要转义,那么出了什么问题?
图片改编自json.org
如需完整且解释清楚的答案,请阅读this amazing Q & A。简而言之,事实证明,
<script>
块中的 <!--<script>
会混淆 html 解析器。 PHP 实际上在json_encode()
中正确地完成了它的工作;
你不能在那里有<!--<script>
,即使它是一个完全有效的 JavaScript 字符串!
我自己做了一些简单的测试。浏览器实际上会忽略<!--<script>
之后的所有内容,所以如果它发生在页面中间,
整个页面的后半部分消失了!我不确定是否有人真的可以在那里注入恶意的东西,比如说,任意执行
代码,但这已经够糟糕了。
还有,
如果$myVarValue
中不仅有一个字符串,还有像array("key" => array("one", "and<!--<script>two", 3))
这样的复杂对象,其中包括<!--<script>
,那还是很糟糕。
如果您有一个纯 HTML 文件(即没有 PHP),并且在您的 <script>
块中的任何位置(甚至在 JavaScript 注释中)都有 <!--<script>
,那也很糟糕。
如果您使用其他非 PHP 的服务器端编程语言并生成 <!--<script>
,那也很糟糕。
如果你的 PHP 是直接输出 JavaScript (Content-type: application/javascript
),其实没问题[1]。
解决方案?使用JSON_HEX_TAG
转义<
和>
(需要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>
它会提醒<!--<script>
。 万岁!
之所以有效,是因为输出中不再有<!--<script>
,因此不再存在 HTML 解析问题。
注意:如果您不打印到<script>
块中,则不需要JSON_HEX_TAG
。
[1] 在这里,“ok”仅仅意味着它没有<!--<script>
问题。不建议动态生成外部 JavaScript 文件,因为它有很多缺点,例如 here、here、here 中的那些。
关于问题2:初始页面加载时间
实际上,这很明显。如果获取$myVarValue
的值所需要的时间较长
(例如,您正在从数据库中获取大量数据),PHP 将不得不等待,浏览器和用户也是如此。
这意味着更长的初始页面加载时间。如果您稍后使用 Ajax 加载数据,它们将没有
等待看到初始结果,但是,Ajax 调用将是一个额外的 HTTP 请求,所以它
意味着更多的服务器工作负载,以及更多的网络负载。
当然,每种方法都有其优点和缺点,因此您必须做出决定。我建议阅读this excellent Q & A。
【讨论】:
@Pang,非常感谢您的时间和详细的示例!由于大多数人不知道这种可能性,我希望它也有助于其他人搜索将 PHP 变量传递到外部 .js 文件。我认为<!--<script>
的情况很常见,所以问题是真实的。【参考方案2】:
很确定这不会破坏它。 json_encode
的全部意义在于倾倒是安全的。
</script>
可能会破坏它,但 PHP 默认将 /
转义为 \/
,因此您不必担心。
【讨论】:
Niet,Yatko,你能在下面测试一下吗?除非我修改字符串文字,否则这不会发出任何警报。也许这只是我的运气不好,但我在不同的浏览器上进行了测试,甚至在 2 个不同的在线 PHP“提琴手”上测试了运行它。非常感谢。<script> <?php $myVarValue = '<!--<script>'; ?> var myvar = <?php echo json_encode($myVarValue); ?>; alert(myvar); </script>
Pang 是对的,它确实破坏了代码:var jsTitle = <?php echo json_encode($h1_title."<!--<script>"); ?>;
- @Pang,您能否解释一下您对JSON_HEX_TAG 的建议。谢谢!以上是关于将 PHP 变量传递给外部 JavaScript(或 jQuery)文件的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章
如何将变量从外部 JavaScript 传递到 HTML 表单
如何从 Blade 格式 HTML 将 PHP 变量传递给 JavaScript 函数