【问题标题】:Wrong document if script dynamically inserted into iframe head如果脚本动态插入 iframe 头,则文档错误
【发布时间】:2014-04-14 17:54:15
【问题描述】:

在 iframe 加载时,我将 google analytics sn-p 插入 iframe 文档 HEAD。

那么sn-p正在插入这个脚本

<script async="" src="//www.google-analytics.com/analytics.js"></script>

在父文档 HEAD 中,我希望它被插入到 iframe 文档 HEAD...


google sn-p是在iframe文档中执行的,为什么会在父窗口文档中插入script标签??

您可以使用它轻松重现并运行 index.html

no_analytics.html 包含:

<!DOCTYPE html>
<html>
    <head>
        <style>body{color: #AAA;}</style>
    </head>
    <body>no analytics</body>
</html>

index.html 包含:

<html>
    <head>
        <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    </head>
    <body>
        <iframe id="insert" src="no_analytics.html"></iframe>
        <script>
            document.getElementById('insert').onload= function() {
                var c =
                    "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){"+
                    "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),"+
                    "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)"+
                    "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');";

                $('#insert').contents().find('head').append($('<script>').html(c));
            };
        </script>
    </body>
</html>

请注意,如果 iframe 已包含 google analytics sn-p,则不会发生这种情况。

【问题讨论】:

  • 如果我的解释中有什么不清楚的地方,请告诉我。这太奇怪了,我真的很好奇!

标签: javascript html iframe google-analytics domdocument


【解决方案1】:

这种行为是因为,您的 jquery 代码将父文档对象作为上下文传递给您的 google analytics sn-p,所以当您的 google analytics sn-p code 是调用 函数检索作为参数父文档对象,您可以使用此示例检查此行为,您可以在 chrome 的开发工具中查看哪个文档指向您的 google 脚本。

no_analytics.html

<!DOCTYPE html>
<html>
  <head>
    <style>body{color: #AAA;}</style>
    <script>
        console.log("document => ", document);
    </script>
  </head>
  <body>no analytics</body>
</html>

index.html

<html>
<head>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
    <iframe id="insert" src="no_analytics.html"></iframe>
    <script>
        document.getElementById('insert').onload= function() {
            var c =
                "(function(i,s,o,g,r,a,m){

                  console.log('document from google script => ', s);

                 i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){"+
                "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),"+
                "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)"+
                "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');";

            $('#insert').contents().find('head').append($('<script>').html(c));
        };
    </script>
</body>

为了让您的示例工作我使用没有 jQuery 的 javascript 代码。

<!DOCTYPE html>
<html>
<head>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
    <iframe id="insert" src="no_analytics.html"></iframe>
    <script>
        document.getElementById('insert').onload = function () {
            var c =
                "(function(i,s,o,g,r,a,m){ console.log('document from google script => ', s);i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){" +
                "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o)," +
                "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)" +
                "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');",
            documentIframe = document.getElementById('insert').contentDocument;

            var script = documentIframe.createElement('script');
            script.innerHTML = c;

            documentIframe.head.appendChild(script);
        };
    </script>
</body>

这是上面脚本的结果

【讨论】:

    【解决方案2】:

    我建议你试试这个:

    $(window).load(function () {
        var c =
            "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){" +
            "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o)," +
            "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)" +
            "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');";
        $('#insert').contents().find('head').append($('<script>').html(c));
    });
    

    【讨论】:

    • 谢谢阿米特,但我刚刚尝试过 仍然插入到父文档中头。
    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多