サーチ…


前書き

同一生成元ポリシーは、リモートアドレスがないスクリプトの同じ起源を持っている場合、リモート・コンテンツにアクセスできるようにするためのスクリプトを防ぐために、Webブラウザで使用されています。これにより、悪意のあるスクリプトが他のWebサイトに機密データを取得する要求を実行することを防止します。

両方のURLが同じプロトコルホスト名およびポートを持つ場合、2つのアドレスの起点は同じとみなされます

同じ出身政策を迂回する方法

クライアントサイドのJavaScriptエンジン(ブラウザ内で実行されるもの)に関しては、現在のドメイン以外のソースからコンテンツを要求するための直接的な解決策はありません。 (ところで、この制限はNode JSなどのJavaScriptサーバツールには存在しません)。

ただし、次の方法を使用して、他のソースからデータを取得することは実際には可能です(状況によっては)。ソリューション制作システムの代わりにハッキングや回避策を提示するものがあることに注意してください。

方法1:CORS

今日の公開APIのほとんどは、CORS(Cross-Origin Resource Sharing)と呼ばれる機能を有効にすることで、開発者がクライアントとサーバーの間で双方向にデータを送信できるようにします。ブラウザは、特定のHTTPヘッダー( Access-Control-Allow-Origin )が設定されているかどうか、および要求元サイトのドメインがヘッダーの値にリストされているかどうかをチェックします。そうであれば、ブラウザはAJAX接続の確立を許可します。

ただし、開発者は他のサーバーの応答ヘッダーを変更できないため、この方法は必ずしも信頼できるものではありません。

方法2:JSONP

JSON with Pの追加は一般的に回避策になると非難されています。それは最も単純な方法ではありませんが、それでも仕事は終わります。この方法では、任意のドメインからスクリプトファイルをロードできるという利点があります。それでも、外部ソースからJavaScriptコードを要求することは常に潜在的なセキュリティ上のリスクであることに言及することは重要です。利用可能な解決策があれば、これは一般的に避けるべきです。

JSONPを使用して要求されたデータは、 JSONです 。これは、JavaScriptでオブジェクト定義に使用されている構文に合致しているため、この転送方法は非常に簡単です。 JSONPを介して取得した外部データをWebサイトに使用させる一般的な方法は、URLのGETパラメータを介して設定されるコールバック関数内にラップすることです。外部スクリプトファイルがロードされると、関数のデータが最初のパラメータとして呼び出されます。

<script>
function myfunc(obj){
    console.log(obj.example_field);
}
</script>
<script src="http://example.com/api/endpoint.js?callback=myfunc"></script>

http://example.com/api/endpoint.js?callback=myfuncの内容は次のようになります。

myfunc({"example_field":true})

この関数は常に最初に定義する必要があります。そうでない場合は、外部スクリプトがロードされたときに定義されません。

メッセージとの安全なクロスオリジン通信

window.postMessage()メソッドと相対イベントハンドラwindow.onmessageを使用すると、クロスwindow.postMessage()通信を有効にすることができます。

ターゲットwindowpostMessage()メソッドは、別のwindowにメッセージを送信するために呼び出すことができます。このメソッドは、そのonmessageイベントハンドラでそれを傍受し、それを精緻化し、必要に応じて送信者ウィンドウに応答を返しますpostMessage()もう一度実行します。

子フレームと通信するウィンドウの例

  • http://main-site.com/index.htmlコンテンツ:

     <!-- ... -->
     <iframe id="frame-id" src="http://other-site.com/index.html"></iframe>
     <script src="main_site_script.js"></script>
     <!-- ... -->
    
  • http://other-site.com/index.htmlコンテンツ:

     <!-- ... -->
     <script src="other_site_script.js"></src>
     <!-- ... -->
    
  • main_site_script.jsコンテンツ:

     // Get the <iframe>'s window
     var frameWindow = document.getElementById('frame-id').contentWindow;
    
     // Add a listener for a response
     window.addEventListener('message', function(evt) {
         
         // IMPORTANT: Check the origin of the data! 
         if (event.origin.indexOf('http://other-site.com') == 0) {
             
             // Check the response
             console.log(evt.data);
             /* ... */
         }
     });        
    
     // Send a message to the frame's window
     frameWindow.postMessage(/* any obj or var */, '*');
    
  • other_site_script.jsコンテンツ:

     window.addEventListener('message', function(evt) { 
    
         // IMPORTANT: Check the origin of the data! 
         if (event.origin.indexOf('http://main-site.com') == 0) {
             
             // Read and elaborate the received data
             console.log(evt.data);
             /* ... */
    
             // Send a response back to the main window
             window.parent.postMessage(/* any obj or var */, '*');
         }
     });
    


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow