我想使用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);


这将产生错误:未捕获的TypeError:无法读取未定义的属性“ addDependency”(第27行)

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

最佳答案

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


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


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


  无法在“文档”上执行“写入”:无法从异步加载的外部脚本写入文档,除非已明确将其打开。


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


  未捕获的TypeError:无法读取未定义的属性“ addDependency”(第27行)


可以将GCL与RequireJS混合使用,但是正如您所看到的那样,这将很混乱。由于必须为此库使用GCL,因此最好对所有内容都使用GCL。如果您无法执行此操作,则可能会发生以下黑客攻击:


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

关于javascript - Require.js和document.write(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30035644/

10-10 00:00