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 而构建的,它有自己的模块依赖系统。更具体地说,它正在做的是:
- 假设它正在同步加载(运行 在页面加载期间)。
- 正在删除任何已加载的现有 GCL 对象。
- 正在安装自己的 GCL 副本(同步加载)。
- 为其目的配置其自行安装的 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。如果您做不到,以下技巧可能会奏效:
- 在 RequireJS 之外,使用普通
<script>
标记同步加载 GCL。
- 将库代码复制到异步加载的模块中。
- 将最后三行(
document.write
s)替换为:window.BLOCKLY_BOOT();
我想使用 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 而构建的,它有自己的模块依赖系统。更具体地说,它正在做的是:
- 假设它正在同步加载(运行 在页面加载期间)。
- 正在删除任何已加载的现有 GCL 对象。
- 正在安装自己的 GCL 副本(同步加载)。
- 为其目的配置其自行安装的 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。如果您做不到,以下技巧可能会奏效:
- 在 RequireJS 之外,使用普通
<script>
标记同步加载 GCL。 - 将库代码复制到异步加载的模块中。
- 将最后三行(
document.write
s)替换为:window.BLOCKLY_BOOT();