【问题标题】:When loading an html page via ajax, will script tags be loaded?通过ajax加载html页面时,会加载脚本标签吗?
【发布时间】:2011-01-13 07:26:34
【问题描述】:

当你使用 AJAX 加载一个 html 文档时,它对 HEAD 标记内的节点做了什么:(script,link,style,meta,title) 忽略它们或加载并解析它们? 而对于 jquery 的 ajax() 函数呢?

【问题讨论】:

    标签: javascript jquery html ajax


    【解决方案1】:

    当您调用jQuery.ajax() 方法时,您可以指定dataType 属性,该属性描述了您希望从服务器获得什么样的数据,以及在收到数据后如何处理。

    默认情况下,jQuery 会尝试根据响应的 MIME 类型猜测 dataType。但是,您可以明确指定以下数据类型:

    • html:以纯文本形式返回 HTML;包含的脚本标签在插入 DOM 时进行评估。

    • 文本:纯文本字符串。

    • xml:返回一个可以通过jQuery处理的XML文档。

    • 脚本:将响应评估为 JavaScript,并将其作为纯文本返回。除非使用“缓存”选项,否则禁用缓存。

    • json:将响应评估为 JSON 并返回一个 JavaScript 对象。

    • jsonp:使用 JSONP 加载到 JSON 块中。将添加一个额外的“?callback =?”到 URL 的末尾以指定回调。

    例如,以下 ajax 调用将数据作为纯文本字符串返回,而不执行脚本或操作 DOM:

    $.ajax({
      url: 'ajax/test.html',
      dataType: 'text',
      success: function(data) {
        alert(data);
      }
    });
    

    【讨论】:

    • 谢谢。真的很有帮助。
    【解决方案2】:

    当你使用 AJAX 加载一个 html 文档时,它对 HEAD 标签内的节点做了什么:(script,link,style,meta,title)

    这取决于您如何进行加载。 ajax()(与它所基于的 XMLHttpRequest 一样)本身只是给你一个字符串。你是怎么把它写进文档的?

    如果您将该字符串写入元素的innerHTML,则不会执行其中的脚本。这在任何地方都没有标准化,但所有当前流行的浏览器都以这种方式运行。

    但是,如果您随后将该元素插入到文档中(无论它之前是否已经在文档中),它在许多浏览器中执行,这是您第一次执行此操作。在 IE 中,当您直接将脚本元素插入到 any 元素中时,脚本将被执行,无论是否在文档中。

    这都是非常不一致和不方便的,这就是为什么你应该避免在文档中 AJAX 加载 <script> 元素。无论如何,通常没有充分的理由;最好让您的脚本代码保持静态,并使用 JSON(或 eval,仅在绝对必要时使用)将脚本数据传递给它们。

    jQuery 的load 函数尝试在AJAX 将内容加载到文档中时补偿浏览器的差异。它无法捕捉到所有涉及<script> 的情况(有一些非常奇怪的情况)。一般来说,你不应该依赖它。您可以通过获取 HTML 页面响应而侥幸,然后只加载没有 <script> 的特定元素,因为这只会执行写入到内部 HTML 的步骤。但同样,你真的不想依赖这个。让服务器返回您的脚本可以直接使用的 HTML 或 JSON 的 sn-p 会更好。

    至于样式表和样式表链接,将它们插入正文中通常会起作用,尽管按照 HTML 的术语来说它可能不应该这样做。 metatitle 不会做任何事情,他们已经太迟了,他们没有效果。仅使用 innerHTML 解析它们不会做任何事情,但如果可以的话,请避免它。

    【讨论】:

    • 这个答案也很有趣。非常感谢。我在 jqmodal 中使用了 ajax 功能,所以我查看了插件的源代码,它使用了 load()。这显然在我的主页中产生了问题。
    • 自 2010 年以来这种情况发生了变化吗?跨浏览器的 ajax 加载脚本仍然不一致吗?
    【解决方案3】:

    当您说“加载”时,我理解这仅仅是指调用 XHR(或 $.ajax 或 $.get 等)从 Web 服务器拉取 XML、JSON 或文本资源,并将其存储在浏览器的 JS 中运行时内存,并获取对它的引用。对于 HTML 资源,该行为本身不会解析任何内容。

    但是,如果您将那个 HTML 注入到 DOM 中(至少在 Firefox 3.5 中),那么 它将被解释。 例如,假设您有以下三个非常专业的文件.

    barf1.html:

    <html>
        <head>
            <script src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js" type="text/javascript"></script>
            <script type="text/javascript">
                $(init);
    
                function init() {
                    $.get('barf2.html', inject);
                }
    
                function inject(data) {
                    debugger;
                    $('body').html(data);
                    //document.write(data);
                }
            </script>
        </head>
        <body>
            long live barf1!
        </body>
    </html>
    

    barf2.html:

    <div>
        <script type="text/javascript">
            alert('barf2!');
        </script>
        <script type="text/javascript" src="barf3.js"></script>
        barf2 lives here now!
    </div>
    

    barf3.js:

    alert('barf3!');
    

    当您导航到 barf1.html 时,页面内容会发生变化,您会看到两个 JavaScript 警报,表明内联脚本块和外部脚本文件都已被解释。

    【讨论】:

      【解决方案4】:

      不,它们不会被解释。

      可以使用innerHTML 或DOM 操作来加载HTML。在这两种情况下,如果 HTML 包含 &lt;script&gt; 标记,它们将不会被解释。

      但是,如果您确实需要,您可以浏览 Ajaxed HTML 内容中的 &lt;script&gt; 标签和 eval() 它。

      但是,如果您使用这种类型的&lt;script src="http://site/script.js"&gt;&lt;/script&gt; 脚本标记,它将被解释。

      【讨论】:

      • 实际上,我在 FF 3.5 中的测试表明内联脚本块已被解释(使用 innerHTML 或 appendChild)。看我的回答。
      • 在我的一些项目中,Firefox 3+ 和 IE7+ 成功地在 jQuery POST 请求加载的 DOM 块中执行
      • 我的回答是相对于一般的 JavaScript 使用,而不是 jQuery。
      【解决方案5】:

      正如已经指出的,一般 - 不,脚本标签不会被解释。

      我完全不确定其他标签会发生什么。

      我在这里假设您正在用 AJAX 加载整个页面 - 我不确定您为什么要这样做?也许你可以给我们更多的信息,我们可以提出一些建议?

      为了更直接地解决您的问题 - 通常,重新加载内容所需的任何脚本不应与内容一起重新加载,而是与页面一起重新加载。这样您就可以安排从您的 AJAX 回调重新附加事件处理程序等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-20
        • 2018-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多