通过ajax加载html页面时,会加载脚本标签吗?

Posted

技术标签:

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

当你使用 AJAX 加载一个 html 文档时,它对 HEAD 标记内的节点做了什么:(script,link,style,meta,title) 忽略它们或加载并解析它们? 而对于 jquery 的 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 回调重新附加事件处理程序等。

【讨论】:

以上是关于通过ajax加载html页面时,会加载脚本标签吗?的主要内容,如果未能解决你的问题,请参考以下文章

通过 AJAX 加载脚本标签

通过 AJAX 加载时 JQuery 脚本不运行

使用Ajax异步加载页面时,怎样调试该页面的Js

ajax 加载内容与普通内容?

PHP JS ajax在页面加载时提交表单,并且一旦另一个函数成功也会触发

使用微调器加载 jQuery 整个 HTML 页面