【问题标题】:How to use jQuery to handle dynamically added script tags in parallel如何使用jQuery并行处理动态添加的脚本标签
【发布时间】:2015-01-22 19:35:30
【问题描述】:

这是我的情况:我通过动态添加了2个脚本

$('body').append('<script src="http://localhost:8080/script_1.js"></script>');
$('body').append('<script src="http://localhost:8080/script_2.js"></script>');

然后我发现它们会按顺序加载,而不是从 chrome 控制台并行加载。

但是,如果我使用本机 js,它们可以并行加载

document.body.appendChild(script);

或jQuery函数:getScript

$.getScript('http://localhost:8080/script_1.js');

我搜索了很多,发现jQuery实际上会删除脚本标签,解析源代码,并使用它的ajax函数$.ajax()来加载脚本,而不是让浏览器来处理。但是 $.getScript() 函数也使用 $.ajax() 并且没有阻塞。显然,这不是 $.ajax() 的错。

这是一个测试用例: 转到http://jquery.com并在控制台中粘贴以下脚本,这将通过jQuery添加一个js文件两次

$('body').append('<script src="/jquery-wp-content/themes/jquery/js/plugins.js"></script>');
$('body').append('<script src="/jquery-wp-content/themes/jquery/js/plugins.js"></script>');

查看时间轴,您会发现它们是按顺序加载的。 当然,我可以使用原生 js 或者上面的 $.getScript() 来节省我的时间。

但是,我想知道为什么?为什么这些来自添加脚本标签的jQuery ajax调用不是并行的?

更新

更有趣的是,该序列似乎只适用于同源的脚本。 我试图从谷歌托管库中加载一些 js 文件,它们是并行的。在http://jquery.com中也尝试过关注

$('body').append('<script src="https://ajax.googleapis.com/ajax/libs/ext-core/3.1.0/ext-core.js"></script>');
$('body').append('<script src="https://ajax.googleapis.com/ajax/libs/ext-core/3.1.0/ext-core.js"></script>');

【问题讨论】:

  • “默认情况下,动态创建并添加到文档的脚本是异步的”,根据this article,但它没有解释为什么 jQuery 附加的本地脚本不是这种情况。跨度>
  • @Moob 是的,我知道...正如我所提到的,我可以使用纯 javascript document.body.appendChild(script); 来加载,是的,它们是并行的...但我只是想知道什么是秘密完成以使我的案件变得连续
  • 在规范 html.spec.whatwg.org/multipage/scripting.html#script 中有一些线索,但是 - 用他们的话来说:“这些属性的确切处理细节,主要是历史原因,有点不重要,涉及到HTML。因此,实现要求必然分散在整个规范中......"

标签: javascript jquery html ajax


【解决方案1】:

在将脚本附加到 DOM 时,根据跨域测试,使用不同的 ajaxTransport 函数。

当我们有一个协议:主机:端口时,会发生跨域请求 不匹配

第一种情况同源

JQuery 使用 XMLHttpRequest open 函数和 async=false 强制同步请求 (see source)。

xhr.open(
        options.type,
        options.url,
        options.async,
        options.username,
        options.password
    );

因此控制台上的警告(至少在 Canary 上)。

主线程上的同步 XMLHttpRequest 已弃用

第二种情况跨域

JQuery 使用 ajax 如下(see source)

script = jQuery("<script>").prop({
                    async: true,
                    charset: s.scriptCharset,
                    src: s.url
                }).....
document.head.appendChild(script[0]);

如您所说,它将并行加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-23
    • 2021-09-30
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2016-12-14
    • 2012-05-17
    相关资源
    最近更新 更多