我有一个远程脚本,在我的页面HTML的HEAD中引用。第一个脚本通过将其附加到DOM来加载和插入另一个脚本。这两个脚本存在于与其嵌入的页面不同的域中。
第一个脚本的内容如下所示:
(function(){
var siteIdentifier = ...
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = '//blah.com/foo/' + siteIdentifier + '/second_script.js';
scriptTag.async = true;
document.getElementsByTagName('head')[0].appendChild(scriptTag);
})();
当我在Chrome(版本43.0.2357.81,64位)中尝试此操作时,我发现第一个脚本在时间轴中很早就加载了。但是,直到DOMContentLoaded事件发生之后才会加载第二个脚本。
以下屏幕截图显示了两个脚本的加载/执行时间表。第一个脚本是顶部项目,第二个脚本是底部项目。忽略中间的项目,这是一个我无法过滤截图时间轴的不同工件。垂直蓝线是DOMContentLoaded事件。
我尝试过使用和不使用异步和延迟,但这似乎没有任何效果。有没有办法强制加载第二个脚本是瞬时的,而不是让它等到DOMContentLoaded事件发生?
更新
我创建了一个使用RawGit和Gist显示问题的示例:
打开Chrome开发人员工具,并在页面加载时查看网络标签。您可以使用时间轴上的滑块缩小特定时间段,并查看何时加载了哪些脚本。您可能需要刷新几次以确保在DOMContentLoaded事件之前已经加载了shim.js,但是您会注意到,无论何时加载shim.js并完成执行,都不会在DOMContentLoaded之前加载second.js。 / p>
注意:我无法使用JSFiddle,因为它不会加载您定义的任何内容,包括外部脚本,直到DOMContentLoaded之后。
更新2:
对于某些背景:我们正在构建嵌入数百个不同网站的第三方产品。第一个脚本实际上是一个垫片,它提取一些识别信息,然后使用识别信息作为URL的一部分调用第二个脚本。我们正在过渡所有人直接使用第二个脚本,但是直到我们所有客户都转换为直接使用第二个脚本,我们需要垫片自动有效地路由它们。第一个和第二个脚本都是动态生成的(即服务器端呈现的)脚本,位于CDN后面。
答案 0 :(得分:0)
正如评论中所指出的,鉴于您的第一个脚本依赖于DOM来加载第二个脚本,我认为您不会发现纯粹的JS解决方案。
我建议编写一个服务器端脚本(如jsp)作为js文件。 您可以将.js扩展名映射为jsp。
在您的服务器代码中,您可以获取传递适当参数的第二个脚本。 <script src="/webapp/jsp_file.js">
然后在jsp文件中使用一些tag libraries来导入第二个js。
这有一个丑陋的缺点,你的服务器成为第二个js的真正客户端 - 可能会导致性能问题&amp;如果它依赖于请求头/ ip过滤,也可能会破坏第二个js文件。