1

我想使用 require.js 异步加载 .js 文件,但我得到的是这个错误: 无法在“文档”上执行“写入”:无法从异步加载的外部脚本写入文档除非它被明确打开。

产生此错误的行位于此文件的最底部: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 property 'addDependency' of undefined (line: 27)

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

4

1 回答 1

3

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

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

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

无法在“文档”上执行“写入”:除非显式打开,否则无法从异步加载的外部脚本写入文档。

使用您的解决方法,您的代码是异步加载的,<script>因此库创建的标签也将异步加载。GCL 加载已启动,但当它立即尝试使用 GCL 的addDependency功能时,由于 GCL 尚未完成加载而失败,您会看到您看到的错误:

未捕获的类型错误:无法读取未定义的属性“addDependency”(行:27)

将 GCL 与 RequireJS 混合可能是可能的,但正如您所看到的,它会很混乱。由于你必须为这个库使用 GCL,你最好只使用 GCL。如果你不能这样做,下面的 hack 可能会起作用:

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