通过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 的术语来说它可能不应该这样做。 meta
和 title
不会做任何事情,他们已经太迟了,他们没有效果。仅使用 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 包含 <script>
标记,它们将不会被解释。
但是,如果您确实需要,您可以浏览 Ajaxed HTML 内容中的 <script>
标签和 eval()
它。
但是,如果您使用这种类型的<script src="http://site/script.js"></script>
脚本标记,它将被解释。
【讨论】:
实际上,我在 FF 3.5 中的测试表明内联脚本块已被解释(使用 innerHTML 或 appendChild)。看我的回答。 在我的一些项目中,Firefox 3+ 和 IE7+ 成功地在 jQuery POST 请求加载的 DOM 块中执行 我的回答是相对于一般的 JavaScript 使用,而不是 jQuery。【参考方案5】:正如已经指出的,一般 - 不,脚本标签不会被解释。
我完全不确定其他标签会发生什么。
我在这里假设您正在用 AJAX 加载整个页面 - 我不确定您为什么要这样做?也许你可以给我们更多的信息,我们可以提出一些建议?
为了更直接地解决您的问题 - 通常,重新加载内容所需的任何脚本不应与内容一起重新加载,而是与页面一起重新加载。这样您就可以安排从您的 AJAX 回调重新附加事件处理程序等。
【讨论】:
以上是关于通过ajax加载html页面时,会加载脚本标签吗?的主要内容,如果未能解决你的问题,请参考以下文章