4

我尝试了许多不同的方法来向谷歌等人提出这个问题,但没有运气。甚至不确定这个问题的标题是否能抓住问题的细微差别。我将尝试解释然后展示实验。我希望有人能够指出发生了什么的一些解释。

鉴于:

  • 在 BODY 结束之前,您有一个脚本 (A),它以编程方式将脚本元素(使用我的首选技术 document.createElement)插入到引用远程脚本 (B) 的文档中
  • 远程脚本 B 执行任何内容的 document.write(例如“hello, world”)
  • 在 BODY 结束之前和脚本 A 之后,您有一个脚本 (C),它引用了一个需要一段时间才能加载的远程脚本(例如 1 秒)

将会发生的是 A 执行,将 B 插入到文档中并开始下载资源。当 B 正在下载时,由于延迟,C 将执行并等待。在 C 等待期间,B 被下载并执行;我们还没有点击 DOMContentLoaded;document.readyState 仍在“加载”中。来自 B 的 document.write 被忽略;狼吞虎咽,好像我们是后 DOMContentLoaded。C 然后完成下载并执行。

实验:

我正在使用 Cuzillion 来制造延迟。如果您查看瀑布图,您还会看到 console.log 消息,它显示所有内容都在 DOM 达到“交互式”就绪状态(即 DOMContentLoaded)之前执行。

我期望在浏览器中的输出是:

TOP
hello, world
hello again, world
BOTTOM

我得到的输出是:

TOP
hello, world
BOTTOM

您会注意到,在我的实验中,我在定义为 A 和 C 之间添加了另一个脚本。我想将其称为 A';它表明,如果您动态添加包含 document.write 的文本(即不是远程脚本)的脚本,则 A' 中的 doc.write 将起作用。

此外,dummy.js 和 CSS 文件来自 JSFiddle。他们不是罪魁祸首;我可以在任何地方重现这个问题。

我知道的事情:

  • 如果您将 C 替换为 IMG,则没有问题
  • 如果将 C 替换为 IFRAME,则没有问题
  • 如果在 C 之后移动 A,则没有问题

现在:

也许这有一个完全正当的理由。必须有,因为我测试过的所有浏览器似乎都以大致相同的方式运行。我想知道为什么?欢迎任何解释、提示和/或指针。甚至像“它在规范中,愚蠢的:)”这样的提示我的脸皮很厚;我应付得来。

免责声明:我讨厌 document.write。我的意图不是以任何方式支持或支持它的使用。然而,考虑到我工作的性质,我现在必须解决它,这种奇怪的事情突然出现在我身上。因此,我想避免“你不应该使用 document.write”这样的评论,因为我已经相信了:)

4

2 回答 2

6

HTML5 不支持从异步加载的脚本执行 document.write,正是因为它很活泼:您无法知道您的脚本是在 DOMContentLoaded 之前还是之后运行。请参阅http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#ignore- destroy-writes-counter和http://www.whatwg.org/specs/web-apps /current-work/multipage/elements.html#dom-document-write步骤 2 和http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#execute-the -script-block第 3 步。关键是,如果脚本在与 DOMContentLoaded 的竞争中胜出,但如果它在竞争中失败则被忽略,这将是非常奇怪的,并且会导致页面有时工作,有时不取决于网络条件。

于 2012-03-21T14:31:43.303 回答
0

SEC7112:来自https://raw.github.com/gist/2141272/1a6bf0111ce10d55e628e3736a9d381d82e8a780/external-with-docwrite.js的脚本由于 mime 类型不匹配而被阻止

这是你的问题。脚本传输为text/plain,它不是 JavaScript 的有效 MIME 类型。

于 2012-03-20T22:00:54.837 回答