通过动态创建的脚本标签异步加载 JavaScript 的 CORS 问题

Posted

技术标签:

【中文标题】通过动态创建的脚本标签异步加载 JavaScript 的 CORS 问题【英文标题】:CORS issue with asynchronously loaded JavaScript through dynamically created script tags 【发布时间】:2015-04-16 20:09:00 【问题描述】:

像下面这样动态创建脚本将异步下载 javascript 源代码。

var script = document.createElement('script');
script.src = src_url;
var first_script = document.getElementsByTagName('script')[0];
first_script.parentNode.insertBefore(script, first_script);

在底层创建了什么类型的请求对象? XMLHttpRequest 对象用于与 AJAX 进行异步数据交换。它是用于使用动态脚本标签进行异步脚本加载的同一对象吗?如果是这样,CORS(Cross Origin Resource Sharing)问题是否也适用于此?

【问题讨论】:

【参考方案1】:

XMLHttpRequest 对象用于与 AJAX 进行异步数据交换。与动态脚本标签用于异步脚本加载的对象是否相同?

不,浏览器只是像加载脚本一样加载它们。

如果是这样,CORS(跨源资源共享)问题是否也适用于此?

没有。 CORS 适用于 XHR 调用和跨域访问,不适用于通过脚本标签加载脚本。这就是JSONP 起作用的原因。

当您将 JavaScript 加载到页面中时,无论您从何处加载它都无关紧要,它会在加载它的页面的安全上下文中运行。因此,例如,如果您有一个位于 http://example.com/foo.html 的页面,并且它从 http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js 加载脚本,那很好(这就是 Google 和 Microsoft 等 CDN 的工作方式,允许我们从那里加载公共库,而不是从我们的自己的服务器)。如果该脚本加载的代码尝试执行 XHR 调用,则适用的来源是 http://example.com,而不是 http://ajax.googleapis.com。类似地,如果该脚本尝试从另一个来源访问窗口(可能http://example.com 页面中有一个来自http://somewhereelse.comiframe),同样适用的来源是http://example.com,因此跨域脚本访问被拒绝。

【讨论】:

非常感谢您的详细回答。这很有意义。顺便问一下,一般浏览器在下载脚本时实际发出的请求是什么类型的?请求被发送到服务器而无需重新加载页面并收到响应。它类似于 AJAX 调用。我有兴趣了解脚本加载案例的幕后机制。 @Md.ArafatAlMahmud:这只是一个标准的 HTTP 请求,就像加载图像或 CSS 文件一样......

以上是关于通过动态创建的脚本标签异步加载 JavaScript 的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

异步加载和延迟加载

React - 转换 HTML 脚本标签以异步加载 SDK

在 div 容器内动态调用异步脚本

提升页面性能的方法

前端性能优化-异步加载

js异步加载的3种方式(转载)