クロスドメイン「ajax」-シンプルなソリューション

次のプロジェクトで、私はajaxでクロスドメインリクエストを積極的に処理する必要に直面しました。このトピックはハブで見たように、特に取り上げたり取り上げたりするものではなかったため、読者と経験を共有することにしました。



ウェブサイトがあるとしましょう
  http://name.my 
Ajaxを使用したいのですが、何が得られますか?

  1. のリクエスト
      http://name.my/ajax.php 
    (私はすべての人が快適になるようにどこにでもPHPを書くでしょう、私自身はJavaで作業します)問題なく答えを返します
  2. のリクエスト
      http://google.com/ 
    アクセスエラーで失敗します
  3. 到達しようとしています
      https://name.my/ajax.php 
    また失敗し、プロトコルが変更されました
  4.   http://name.my:81/ajax.php 
    そしてアドレスの別のポートはラズベリーを台無しにします


タスク:動作するリクエストを送信するためのクロスブラウザソリューションを見つけます:ie7 +、opera 9.6 +、ff 3 +、chrome、safari。 また、httpからhttpsに連絡する必要もあったため、ieに「混合コンテンツ」メッセージが表示されることはありません。

JQueryはサイトのライブラリとして使用され、組み込みのクロスドメインクエリメカニズムはありません(jsonpを整理する機能は1.5で登場しましたが、これは常に機能するとは限りません)。プラグインの検索も結果を生成しませんでした。 したがって、単純なパス(原則として予想されていた)で中断して、Googleに行きましたが、明確な答えもありません-私には合わない方法や物事の詳細が見つかりました(たとえば、dojoでそのようなリクエストをリリースするが、すべてのjsを変更するサイトは非常に労働集約的です)。

次の手法を使用して問題を解決できます。

  1. postMessage
  2. ジョンソン
  3. CORS
  4. document.domainのメソッド
  5. window.nameトランスポート
  6. サーバー側プロキシ
  7. クレイジー・フレーム・スタッフ
  8. 閃光


初心者、このリストを見ると、恐ろしくなります(原則として、私も幸せではありませんでした)。 したがって、私たちの仕事は、問題を解決する最良の方法を見つけることです。これにより、サイトに余分な松葉杖が作成されることはありません。

1)postMessageはHTML5標準の新機能で、ウィンドウ間でメッセージを送信できますが、ウィンドウのコンテンツは異なるドメインからでもかまいません。 targetWindow.postMessage(message、targetOrigin)の実装例; targetWindow-リクエストを送信するウィンドウ、message-メッセージ、targetOriginウィンドウで開くターゲットドメイン。「*」をドメインとして指定することができ、どのドメインでも可能です。

2)JSONP(JSON Padding)または「JSON padded」は、コールバック関数の名前が入力引数として指定されている場合のJSON拡張です。 タグを使用すると、他のドメインにアクセスできますが、結果は処理できないjson応答の形式になります。jsonpは次のソリューションを提供します。関数の名前をサーバーに渡すと、応答に裸のデータがなく、parseResponse({"paper": 「A4」、「count」:5})、parseResponse関数を呼び出します。

3)CORSは大きなトピックであるため、welのw3cドキュメントに興味がある人を簡単に説明します。 XMLHTTPRequest 2は新しいリクエスト仕様であり、機能し、通常のXMLHTTPRequestのように呼び出されます(つまり、XDomainRequest)が、現在、httpヘッダーに次が追加されています。

Access-Control-Allow-Originは、接続を許可するドメインを決定します。

Access-Control-Allow-Credentialsは、リクエストを実行する権限を示します(Access-Control-Allow-Credentials: "Access-Control-Allow-Credentials" ":" true true:%x74.72.75.65; "true"、大文字と小文字を区別します)

Access-Control-Max-Age-結果がキャッシュされる期間。

また、使用可能なメソッド(GET、POST)を決定することもできます。また、仕様のすべての追加ヘッダーフィールドを確認できます。

メソッドの主な問題は、すべてのブラウザがそれをサポートしているわけではなく、IE-XDomainRequestからの実装を使用したい人は、IEがレパートリー内でhttpプロトコルからhttpsへのリクエストを許可しないことを忘れないでください。 httpsからhttp)ですが、それはつまりです。

4)共通のスーパードメイン、つまりtest1.name.myとtest2.name.myの2つのサイトと通信する場合、document.domainが適しています。 これらのサイト間に通常のリクエストはありませんが、ドキュメントにはドメインプロパティがあり、両方のウィンドウでname.myに変更し、iframeを介して通常の方法で通信できます。

5)window.nameトランスポート-ウィンドウのnameプロパティを変更し、シリアル化されたデータのプロパティをテキストで送信します。

6)サーバー側プロキシ-最も簡単な解決策は、リクエストをサーバーにプロキシすることです。 つまり、name.myは、たとえばname.my/proxy/name2.my/test.htmlなどの特別なURLに特別な要求を行い、name.myサーバーはそれをname2.my/test.htmlにプロキシします。

画像 7)CRAZY IFRAME STUFF-メソッドの本質は、iframeは、異なるドメイン上にあっても、アドレスフラグメントの識別子を変更することで互いに通信できることです(識別子は「#」の後のアドレスにあるものです)#fragmentの連続した変更によって双方向に送信できるデータストリームが生成されます。 フラグメント識別子はテキストであるため、送信するすべてのデータは(de)シリアル化する必要があります。つまり、JSON +に変換する必要があります。表示ウィンドウのアドレスに影響を与えないように2つのiframeが必要です。

8)フラッシュ-フラッシュを中間インターフェースとして使用します(別のトピック。その微妙な点もすべて記事に記載されています)

インターネットを検索した後、素晴らしいライブラリeasyxdm.net/wpを見つけました。 最もおいしいのは作業方法です。ブラウザとそのバージョンに基づいて、最も高速で最新の方法が選択されます。



postMessageをサポートしない他のブラウザーでは、#hashの交換に基づいたテクノロジーが使用されますライブラリー関数はajaxのみに限定されず、主に会話についてです。

そこで、easyxdmを使用してajaxリクエストを実装することから始めます。

プロキシオブジェクトを直接作成して、リクエストを送信します。

     var xhr =新しいeasyXDM.Rpc({
         remote: "http://name.my/cors/index.html" //プロバイダーへのパス
     }、{
        リモート:{
            リクエスト:{} 
         }
     });




easyXDMは、いわば、コンストラクターを持たず、シングルトンパターンを実装する静的クラスです。

ヘルメットリクエスト自体:

 xhr.request(
     {
         url: "pathRelativeToRemote / getrest /"、//リクエストのアドレス
        メソッド:「POST」、
        データ:{foo: "bar"}
     }、関数(応答){//応答結果を処理するための関数
        アラート(response.status);
        アラート(response.data);
     }
 );




より詳細に:基本設定を設定する最初のパラメーター、特に、ここでは、事前に準備されたファイル「provider」(corsフォルダーのアセンブリとアーカイブ内にある)へのパスを指定します。



私はリモートサーバー上にあり、必要なURLへのリクエストをプロキシし、利用可能な方法の1つを使用して回答を送信します。

ただし、ここでは、フラッシュドライブへのパスも入力する必要があることを忘れないでください(フラッシュドライブはlibにも接続されています)。これにより、IEの古いバージョンが接続を確立します。



次に、リモートメソッドの構造を作成します。ここでリクエストが宣言されます(ファイルname.my/cors/index.htmlに 、同様のメソッドの構造も作成する必要があります)。

xhr.request関数を呼び出すことで、リクエストをプロキシファイルname.my/cors/index.html送信します。これは、URLをノックし、そこにデータパラメーターを渡します。通常のajaxを使用して、応答を受信すると、データを送信します(必要に応じて応答を部分に分割します)最後のパラメーターで渡したコールバックが呼び出されるホストに。

ファイルname.my/cors/index.htmlに少し触れますが、これはリクエストの不可欠な部分であり、まず、データの返送と受信を整理します。 第二に、彼は素晴らしいパンを持っています-彼は自分の手段でCORSを実装しています:

var useAccessControl = true; //サーバーからのヘッダーの受け入れを許可(true)または禁止(false)します(これにより、サーバーが誤ってサードパーティドメインへのデータ送信を許可しないようにします)

var alwaysTrustedOrigins = [(/\.?easyxdm\.net/)、(/ xdm1 /)]; //許可されたサーバーのリスト

var remoteは、リモートメソッドの構造を実装する必要があるeasyXDMオブジェクトです。



また、古いブラウザー用に、easyXDMでアクティブに使用されるJSONオブジェクトを実装する小さな「ライブラリ」json2.jsを接続することも忘れないでください(一方、easyXDMは、独自のシリアライザーを作成してパラメーターとして渡すことを妨げることはありませんが、非常にまれなニーズのようです)。



私のプロジェクトには、Ajaxを介してさまざまなフォームを送信するタスクがあったため、指定されたフォームをajax経由でシリアル化して送信する便利なツールが必要でした。 解決策はjQuery Formプラグインに直面してすぐに見つかりましたが、プラグインはjqに関連付けられているため、クロスドメインリクエストの送信を拒否します。

構造に影響を与えずにjQueryを通常のajaxハンドラーのままにすることなく、クロスドメインリクエストをプラグインに埋め込む簡単な方法を紹介します。

htmlフォームがあります(フォーム内でこれについて心配していないという事実は、プラグインによって行われます)。

  <form action = "name2.my" id = "myform" method = "POST"> ... </ form> 


事前にクロスドメインリクエスト用にオブジェクトを準備します。

 crossAjax =新しいeasyXDM.Rpc({
              remote: 'name2.my/cors'、//リモートサーバー上のプロバイダー
              swf: 'name.my/easyxdm.swf'
	 }、{
             リモート:{
             リクエスト:{} 
	 }
 });




以下は、すべてのフォームフィールドが自動的にシリアル化されるプラグイン接続コードです。フォームを送信するURLは、フォーム自体のアクション(メソッドなど)から取得されます。

 $( '#myform')。ajaxForm({
     beforeSubmit:beforeSubmit、  
    成功:showResponse
 });




これは結果を処理する方法であり、まったく触れません。

 showResponse = function(responseText、statusText、xhr、form){ 
    ここで私たちは私たちの答えで何かをしています
 }




しかし、主な焦点はbeforeSubmitにあり、フォームが送信される前にメソッドが呼び出されるため、ここでシリアル化されたデータを取得し、リクエストの送信を中断することができます(これが必要です)。

 beforeSubmit = function(arr、form、options){
     if(options.url.indexOf(location.host)<0){//ホストがリモートの場合、メソッドを使用します
         var json = {};
         for(var i = 0; i <arr.length; i ++){//シリアル化されたフォームデータを、シリアル化の準備ができた通常のjsオブジェクトに変換します(フォーム自体は非常に奇妙な方法でそれらを渡します)
             json [arr [i] .name] = arr [i] .value;
         }
         crossAjax.request({//ヘルメットクロスドメインリクエスト、パラメーターの置換
                 url:options.url、
                メソッド:「POST」、
                データ:json
             }、関数(応答){
                 switch(response.status){//回答を解析する
                    ケース200:
                         showResponse(JSON.parse(response.data)、response.status、arr、form)
                        休憩;
                    デフォルト:
                         alert( "エラー:" + response.status);
                        休憩;
            }
         });
         falseを返します。  // jQからのネイティブajaxリクエストを停止します
     }
 } 




このようなものは、問題のあるタスクを簡単に解決できます。 実例は図書館のウェブサイトで見つけることができます。 これで、最初の「Habrapost」を締めくくります。

ライブラリ自体



All Articles