Require.js 和 document.write()

Require.js and document.write()

我想使用 require.js 异步加载 .js 文件,但我得到的是这个错误: 无法在 'Document' 上执行 'write': 除非显式打开,否则无法从异步加载的外部脚本写入文档。

产生此错误的行位于该文件的最底部:https://code.google.com/p/blockly/source/browse/trunk/blockly_uncompressed.js?r=1234

所以我尝试了一个解决方法:

var head = document.getElementById('head');
var myScript= document.createElement('script');
script1.innerHTML = "...";
head.appendChild(myScript);

这会产生错误:Uncaught TypeError: Cannot read 属性 'addDependency' of undefined(行: 27)

我该如何解决这个问题?非常感谢。

您尝试加载的库是为使用 Google Closure Library 而构建的,它有自己的模块依赖系统。更具体地说,它正在做的是:

  1. 假设它正在同步加载(运行 在页面加载期间)。
  2. 正在删除任何已加载的现有 GCL 对象。
  3. 正在安装自己的 GCL 副本(同步加载)。
  4. 为其目的配置其自行安装的 GCL 对象。

它通过使用 document.write 创建 <script> 标签来完成这些步骤。在页面仍在加载时调用 document.write 会导致写入的 HTML 附加到页面,而在页面加载完成后调用它会覆盖页面。如果脚本是异步加载的,它会在脚本加载和页面加载之间产生竞争条件,因此在这种情况下禁止使用 document.write,并且会出现您看到的错误:

Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

使用您的解决方法,您的代码是异步加载的,因此库创建的 <script> 标记也是异步加载的。 GCL 加载已启动,但是当它立即尝试使用 GCL 的 addDependency 函数时,它失败了,因为 GCL 尚未完成加载,并且您看到了错误:

Uncaught TypeError: Cannot read property 'addDependency' of undefined (line: 27)

将 GCL 与 RequireJS 混合使用是可能的,但如您所见,它会很混乱。由于您必须为此库使用 GCL,因此最好只对所有内容使用 GCL。如果您做不到,以下技巧可能会奏效:

  1. 在 RequireJS 之外,使用普通 <script> 标记同步加载 GCL。
  2. 将库代码复制到异步加载的模块中。
  3. 将最后三行(document.writes)替换为:window.BLOCKLY_BOOT();