前回の記事「JavaScriptの実行順序を保証する方法 - jQuery.htmlの徹底分析」では、jQuery.html関数が使える理由を明らかにしました。さまざまなブラウザ 動的 JS を連続的に実行し続ける秘訣は、外部 JavaScript の同期 AJAX 取得です。
<script> <br>$(function(){ <br>$('#container').html('<script src= ./service.ashx?file=js/jquery-ui.js&lay=2000" type="text/javascript"></script>' '<script>alert(typeof(jQuery.ui));< /script>')>}); <br></script>
>< ;/div>
ちなみに、この方法で読み込まれた外部 JavaScript は、AJAX 以降ではデバッグできません。最後に、外部 JavaScript の解析とインライン JavaScript の解析は同じです (どちらも jQuery.globalEval を呼び出します):
この記事の主題に移りましょう: ロードされた JS が別のドメインにある場合でも、jQuery.html は各ブラウザーでの JS の順次実行を保証できますか?
2. テストケースを作成します
1) 2 つのドメイン名を準備します
テスト用に、個人のホームページ (http://sanshi.me/) の下に一時的に 2 つのサブドメインを作成しました。それぞれ:
http://test.sanshi.me/
http://test1.sanshi.me/
2) デモページ (test2_1.htm) を更新します
test2_1 を追加します。 htm は最初のサブドメイン名の下に配置され、アクセスアドレスは http://test.sanshi.me/jsorder/test2_1.htm です。そのソースコードは次のとおりです。 コードをコピーします
コードは次のとおりです:
title> <script> { </div>$( '#container').html('<script src="http://test1.sanshi.me/jsorder/service.ashx?file=js/jquery-ui.js&lay=2000" タイプ="text/javascript" ></script>' <script>alert(typeof(jQuery.ui));</script>');
/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. Postscript
Originally this series of articles should have ended here. However, after I tested jQuery1.5.1, I actually found that it was different from the jQuery1.4.4 I used. I had long heard that jQuery1.5.1Refactored the AJAX part. Unexpectedly, it really had some impact on our code.
For the specific impact, please see the next article: How to ensure the execution order of JavaScript - between jQuery1.5.1 and Slight differences in jQuery1.4.4. to be continued. . .