JAvascriptのドメイン間リクエスト


  • あっさり
  • ところで、1960年代初め、アメリカカリフォルニア州の森尼維爾市で、彼の最初の泣き声とともに、Brendan Eichは彼の一生を始めた.普通の子供と同じように、彼は楽しい子供時代を過ごし、愚かな青年時代を過ごし、学士と修士号を順調に卒業し、プログラマーの生活を始めた.
    卒業後、Silicon Graphicsで7年間オペレーティングシステムとネットワークプログラミングをした(まさか一人の会社の感情も7年間かゆい).
    彼の実家を離れた後、MicrokernelとDSPプログラミングを遊び始めたMicrokernelは、MIPSアーキテクチャのgcc R 4000ポートに初めて接触した.
    彼はNetscapeとMozillaの時に事業の頂点に達した.1995年4月、彼はMochaをプレイし始め、彼のしばらくの努力を経てMochaは強くなった.そこで同年の9月、華麗な変身を遂げ、livescriptに改名し、Netscape Navigator 2.0に初めて装着された.同年12月4日、Sun社との共同声明でlivescriptが最終形態に変身し、JavaScript神兵が誕生した.
    JavaScript神兵が強すぎたため、人々は彼に封印を加えた.しかし人はいつも私心があって、そこでまたいくつか封印の方法を開けることを残しました.
    薄く引っ張ってしまいましたが、封印と封印を解く方法を紹介します.
    Same origin policy
    まず、ドメイン間アクセスを封印し、javascript同源ポリシーの制限、すなわちa.comドメイン名のjsはb.comドメイン名のオブジェクト(ドメイン間)を操作できない.以下にいくつかの例を挙げて、もっとイメージ的に見えます.
    URL 1
    URL 2
    通信を許可するかどうか
    コメント
    http://www.a.com/a.js
    http://www.a.com/b.js
    はい
    同ドメイン名
    http://www.a.com/a.js
    http://www.a.com:8080/b.js
    いいえ
    ドメイン名と異なるポート
    http://www.a.com/a.js
    https://www.a.com/b.js
    いいえ
    ドメイン名と異なるプロトコル
    http://www.a.com/a.js
    http://127.0.0.1/b.js
    いいえ
    ドメイン名とそのIP
    http://www.a.com/a.js
    http://www.b.com/b.js
    いいえ
    メインドメイン名サブドメイン名
    http://www.a.com/a.js
    http://www.b.com/b.js
    いいえ
    異なるドメイン名
    Same origin policyに何か分からないことがあったらhttp://en.wikipedia.org/wiki/Same_origin_policy見てください.
    以下に、ドメインを越えてこの封印にアクセスするいくつかの主要な手跡を解く.
    手印一JSONP、すなわちJSON with Padding.同源ポリシーの封印の制限により,ドメイン間アクセスが封印された.封印を解いてドメイン間リクエストを行う必要がある場合はhtmlのscriptタグを使用してドメイン間リクエストを行い、responseで実行するjavascriptコード、JSONオブジェクトなどを返す.このように封印を解いてドメイン間で要求する方式をJSONPと呼ぶ.
    www.a.comドメイン名の下に以下のhtmlファイルがあります.
    
    <html>
    <head>
    </head>
    <body>
    <script type="text/javascript" id="script1"></script>
    <input type="text" id="a" name="a">
    <input type="button" value="click" onclick="document.getElementById('script1').src='http://www.b.com/response.js'">
    </body>
    </html>
    

    www.b.comでのレスポンスのresponse.jsコード
    
    var a=1;//    
    alert("Hello World");//    
    document.getElementById("a").value="Hello World";//    
    

    多くの場合、ダイナミックのために私たちはこのように遊んでいます.www.a.com下のhtmlを
    
    <html>
    <head>
    </head>
    <body>
    <script type="text/javascript" id="script1"></script>
    <input type="text" id="a" name="a">
    <input type="button" value="click" onclick="document.getElementById('script1').src='http://www.b.com/response.jsp'">
    </body>
    </html>
    

    www.b.com/response.jsをresponseに変更する.jsp
    
    <%out.print("var a=1;alert(\"Hello World\");document.getElementById(\"a\").value=\"Hello World\"");%>
    

    URLにはpが1つしかないが、手印JSONPは封印を解くと同時に破壊力を持つようになる.
    手印JSONPに加え、仙人YUI、Jquery、Dojo、Extなどが独自の手印を次々と研究している.
  • YUI
  • まず仙人YUIがどんな仕事をしたか見てみましょう.
    YUI3.2のjsonpの使い方は以下の通りです(以下、YUI 3.2を中心に分析します):
    
    var url = "http://yuilibrary.com/gallery/api/random?callback={callback}";
    function handleJSONP(response){//...};
    //...
    Y.jsonp(url,handleJSONP);
    //...
    

    ps:ソースコード中examples/jsonp/jsonp_gallery.htmlには詳細があります.
    印刷が速く、呼び出しが便利で、どのように実現されているかを見てみましょう.
    ダウンロードhttp://developer.yahoo.com/yui/3/,Full Developer Kit版を選択,yui_3.2.0.zip解凍後、yui/buil/jsonpディレクトリに6つのファイルが表示されます.
    jsonp.js
    jsonp-debug.js
    jsonp-min.js
    jsonp-url.js
    jsonp-url-debug.js
    jsonp-url-min.js
    主にjonpを見てください.jsというファイルは、8行目に
    
    YUI.add('jsonp', function(Y) {
    //...
    

    YUIというfunctionにjsonpというfunctionを動的に追加しました.後のコードには、おなじみのprototype、apply、unshiftなどのJavaScript神兵の秘法が使われており、一つ一つ分析せず、133行目から137行目のコードを直接見ています.
    
    //...
            Y.Get.script(url, {
                onFailure: wrap(config.on.failure),
                onTimeout: wrap(config.on.timeout),
                timeout  : config.timeout
            });
    //...
    

    ここにY.Get.がありますscript(...)の呼び出しは、url、onFailure、onTimeout、timeoutパラメータがありますが、これはいったい何をしているのでしょうか.
    yui/build/yui/getを見てください.jsというファイル.
    30行目から726行目はきれいな閉包をしながらY.Getに値を付けた.505行から725行を見ると、Y.Getはこのように成長していることがわかります.
    
    {
        PURGE_THRESH:20,
        _finalize:function(id){ ... },
        abort: function(o) { ... },
        script: function(url, opts) { return _queue("script", url, opts); },
        css: function(url, opts) { ... }
    }
    

    やっと上記のY.Get.を見つけました.scriptというfunctionですが、中には別の穴があり、もう一つあります.queur(...)の呼び出しは、虎穴に入らないと虎子にならない、これを見てください.queueのfuncitonにはいったい神馬浮雲があるのか.
    362行にジャンプして、見つけました_queueの実装.でも焦らないで、まず上の353から361の注釈を見てください.
    
        /**
         * Saves the state for the request and begins loading
         * the requested urls
         * @method queue
         * @param type {string} the type of node to insert
         * @param url {string} the url to load
         * @param opts the hash of options for this request
         * @private
         */
    

    と言いますqueueはrequestの状態を保存し、loadを開始します.コードを見てください.372行から378行、389行目のコード:
    
    //...
            queues[id] = Y.merge(opts, {//  merge        , yui/build/yui/yui.js 。
                tId: id,
                type: type,
                url: url,
                finished: false,
                nodes: []
            });
    //...
    _next(id);
    //...
    

    requestを保存した状態が実現したことが判明し、ここではloadを実現していないのではなく389行目に複数の_next(id)の呼び出し.これはnext(...)いったい何をしているのでしょうか.(この_nextが主役なので、詳しく分析します)
    
    //...
            d = w.document;
            h = d.getElementsByTagName("head")[0];
    //...
            if (q.timeout) {
                // q.timer = L.later(q.timeout, q, _timeout, id);
                q.timer = setTimeout(function() { 
                    _timeout(id);
                }, q.timeout);
            }
    //...
                n = _scriptNode(url, w, q.attributes);
    //...
            if (insertBefore) {
                //...
            } else {
                h.appendChild(n);
            }
    //...
    

    まずdocumentを取って、それからhを受け取ってheadラベルだけを考えて、nは通過します_scriptNode再着_node、documentを返します.createElement("script"),nodeにはきれいなfor(i in attr){...}ループはプロパティバインドを完了しました.最後に、insertBefore要素が指定されていない場合は、headラベルに、上に作成したscriptラベルappendを入れます.
    これで仙人YUIのJSONP実現分析が完了した.次に、仙人JqureyがJSONPをどのように実現したのかを分析します.
  • Jquery
  • ログインhttp://jquery.com/、DEVELOPMENT(179 KB、Uncompressed Code)を選択してソースコードをダウンロードし、これはPRODUCTION(26 KB、Minified and Gzipped)よりも快適に見えます.
    まずJqueryでJSONPの使い方を見てみましょう.上の例の多くは$である.getJSON、しかも紹介が良かったです.JEには多くの牛人が具体的な分析と実現過程を書いた.審美疲労がある人がいるので、次の例はもっと強い$を使っています.ajax({dataType:'script'...}).jsonだけでなくscriptコードがロードされているからです.次はどうやって使うか見てみましょう.
    
        $.ajax({
            url: "http://2520011.appspot.com/js/cross_domain_demo.js",//       GAE      js
            dataType: 'script',
            success: function(data ){
                alert(data);
            }
        });
    

    インタフェースのapiのデザインも便利で、次に彼がどのように実現したかを見てみましょう.
    ソースコード5762行でajaxの実装を見つけた.真ん中に積み重ねられた関係のないコードをスキップして5859行に来て、ここで柳暗花明になって、私たちはやっと長い間求めていたソースコードを見つけました.
    
    var head = document.getElementsByTagName("head")[0] || document.documentElement;
    var script = document.createElement("script");
    //...
    script.src = s.url;
    //...
    head.insertBefore( script, head.firstChild );
    

    挿入を含めて4行...Jqueryは本当に簡素です.牛人は普通そうでしょう、O(∩∩)Oはははは~
    ここまで仙人Jqueryの実现を分析して、本当に1つの牛に比べて、次の段、私达はいっしょにDojoの実现を分析します.
    to be continued......
    ps:月曜日から金曜日まで毎日少なくとも1週間、週末は休みです.