zoukankan      html  css  js  c++  java
  • [原创]如何确保JavaScript的执行顺序 – 之jQuery.html并非万能钥匙

    上一篇:

    1.     引言

    在上一篇文章《如何确保JavaScript的执行顺序 - jQuery.html深度分析》中,我们揭示了jQuery.html函数之所以能在各种浏览器下保持动态JS顺序执行,其秘密在于 – 同步AJAX获取外部JavaScript

     

    我们先来简单回顾下HTML源代码(test2.htm):

    <html>

    <head>

        <title></title>

        <script src="js/jquery-1.4.4.js" type="text/javascript"></script>

        <script>

            $(function(){

                $('#container').html('<script src="./service.ashx?file=js/jquery-ui.js&delay=2000" type="text\/javascript"><\/script>' + '<script>alert(typeof(jQuery.ui));<\/script>');

            });

        </script>

    </head>

    <body>

        <div id="container">

        </div>

    </body>

    </html>

     

    顺便一提的是,通过这种方式加载的外部JavaScript不可以在Firebug中调试,因为AJAX结束后外部JavaScript的解析和内联JavaScript的解析是一样的(都是调用jQuery.globalEval):

     

    下面进入本篇文章的主题:如果加载的JS是在其它域下面的,jQuery.html还能在各个浏览器下都能保证JS的顺序执行么?

    2.     建立测试案例

    1)     准备两个域名

    为了测试,我在个人主页(http://sanshi.me/)下面临时创建了两个子域名,分别是:

    http://test.sanshi.me/

    http://test1.sanshi.me/

     

    2)     更新Demo页面(test2_1.htm

    我会把test2_1.htm放在第一个子域名下,访问地址为http://test.sanshi.me/jsorder/test2_1.htm,其源代码如下:

    <html>

    <head>

        <title></title>

        <script src="js/jquery-1.4.4.js" type="text/javascript"></script>

        <script>

            $(function () {

                $('#container').html('<script src="http://test1.sanshi.me/jsorder/service.ashx?file=js/jquery-ui.js&delay=2000" type="text\/javascript"><\/script>' + '<script>alert(typeof(jQuery.ui));<\/script>');

           

            });

        </script>

    </head>

    <body>

        <div id="container">

        </div>

    </body>

    </html>

    可以看到,其中的jQueryUI脚本指向的是第二个域名下的(test1.sanshi.me)。

     

    3)     在不同浏览器下测试

     

    test2_1.htm

    使用jQuery.html函数动态加载其它域下的JavaScript

    Firefox 3.6

    IE 8

    Chrome 10

    Safari 4

    Opera 11

     

    3.     jQuery.html并非万能钥匙,那么

    不知道大家是否还记得我们在第一篇文章中提到的test3.htm不,这个结果和那个示例的结果一模一样,jQuery.html也并非万能钥匙。这不禁让我们怀疑这两个示例的内部逻辑是否一样?

     

    但是第二篇文章不是明明白白告诉我们,jQuery.html使用的是同步AJAX的机制来加载外部JS的么?等等。。。。。。

     

    大家有没有从上面的分析中发现问题,AJAX来加载其他域的资源,这不是明摆着违背了大名鼎鼎的同源策略(Same Origin Policy)了么?所以jQuery不可能这么实现,我们来看看jQuery.ajax文档是怎么说的:

    看来我们在第二篇文章中看到的这个函数(evalScript)内部并非真的通过同步AJAX来获取数据:

     

    4.     深入jQuery.ajax函数,看看怎么加载不同域下的JS文件

    注释已经写的很清楚了,如果是通过GET方式请求JavaScript文件,并且这个文件是在其他域下面的(remote),那么就通过在head中添加script标签来处理,而不是走AJAX的流程。所以在这个条件分支结束的时候,直接从函数体返回:

     

    经过分析,我们发现在动态加载不同域的JavaScript时,jQuery.html其实采用了在head中添加script标签的做法(不管是外部JS或者内联JS),这和我们在第一篇文章中提到的test3.htm是一模一样的逻辑,这也验证了我们的想法:

     

    由此可见,如果想兼容CDN加速静态资源的情况,还必须使用第一篇文章中提到的“方案一,如何在动态添加script标签时确保执行顺序”。

    5.     后记

    本来这个系列的文章到这就应该结束了。不过在我测试jQuery1.5.1后,居然发现和我用的jQuery1.4.4是有差异的,早就听说jQuery1.5.1AJAX部分进行了重构,没想到还真的对我们的代码有点影响。

     

    具体是哪方面的影响,请看下一篇文章:如何确保JavaScript的执行顺序 - jQuery1.5.1jQuery1.4.4的细微差异。待续。。。

     

     

  • 相关阅读:
    Eclipse中输入系统变量和运行参数
    poi大数据导入解决方法
    技术走向管理一些思考(2)-建立管理思维
    C. Diverse Permutation(Codeforces Round #275(div2)
    mysql大数据高并发处理
    UVa 11849
    centos7;windows下安装和使用spice
    HDU-4819-Mosaic(二维线段树)
    Using a Plugin
    CSU1608: Particle Collider(后缀数组)
  • 原文地址:https://www.cnblogs.com/sanshi/p/how_jquery_ajax_process_cross_domain_script.html
Copyright © 2011-2022 走看看