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

Yat*_*tko 5 javascript php jquery json

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

PHP代码中的js

<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>
Run Code Online (Sandbox Code Playgroud)

外部 .js

var siteURL=jsBaseurl;
alert(siteURL+jsTitle+jsSubtl)
Run Code Online (Sandbox Code Playgroud)

它工作正常,我的问题是关于以下意见biplav:

警告:这可能会导致您的网站被盗.例:

<?php $myVarValue = '<!--<script>'; ?>
Run Code Online (Sandbox Code Playgroud)

有关详情,请参阅此问题.解决方案:使用 JSON_HEX_TAG转义<和>(需要PHP 5.3.0).-

另一个缺点是影响初始页面加载时间.- biplav

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

Pan*_*ang 8

关于问题1:使用JSON_HEX_TAGjson_encode()

  • 示例1
    考虑这段简单的代码.

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

    输出:

    <script>
        var myvar = "hello world";
        alert(myvar);
    </script>
    
    Run Code Online (Sandbox Code Playgroud)

    它提醒hello world.好.

  • 示例2
    让我们尝试使用</script>字符串.

    <script>
        <?php $myVarValue = '</script>'; ?>
        var myvar = <?php echo json_encode($myVarValue); ?>;
        alert(myvar);
    </script>
    
    Run Code Online (Sandbox Code Playgroud)

    输出:

    <script>
        var myvar = "<\/script>";
        alert(myvar);
    </script>
    
    Run Code Online (Sandbox Code Playgroud)

    它提醒</script>.好.

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

  • 示例3
    现在,请考虑这个非常特殊的字符串:<!--<script>

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

    输出:

    <script>
        var myvar = "<!--<script>";
        alert(myvar);
    </script>
    
    Run Code Online (Sandbox Code Playgroud)

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

    如果你检查JSON的规范,没有一个字符<!--<script>需要被转义,那么出了什么问题?

    JSON字符串

    图片改编自json.org

如需完整且解释清楚的答案,请阅读这个惊人的问答.简而言之,事实证明, <!--<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>
Run Code Online (Sandbox Code Playgroud)

输出:

<script>
    var myvar = "\u003C!--\u003Cscript\u003E";
    alert(myvar);
</script>
Run Code Online (Sandbox Code Playgroud)

它提醒<!--<script>.欢呼!

它的工作原理是因为<!--<script>输出中没有其他内容,因此不再有HTML解析问题.

注意:JSON_HEX_TAG如果您没有打印成<script>块,则不需要.

[1]在这里,"ok"仅仅意味着它没有<!--<script>问题.不推荐动态生成外部JavaScript文件,因为它有很多缺点,例如此处,此处,此处所述的缺点.


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

实际上,这很明显.如果获取值所需的时间$myVarValue很长(例如,您从数据库中获取大量数据),PHP将不得不等待,浏览器和用户也是如此.这意味着更长的初始页面加载时间.如果您稍后使用Ajax加载数据,他们将不必等待查看初始结果,但是,Ajax调用将是一个额外的HTTP请求,因此这意味着服务器的工作量会增加,并且会增加负载.网络.

当然,每种方法都有其优点和缺点,所以你必须自己决定.我建议阅读这个优秀的问答.