[JavaScript General] Ajax クロスオリジン通信の3つの手法

こちらの記事が分かりやすかった。

このクロスドメインの問題に対応する一般的手法として、伝統的ないくつかの方法があるので簡単に紹介します。
どの方法も「呼ばれる側の承諾」が必要である (= サーバー側がそのように作られていなければ利用できない) という点がポイントであり、セキュアな手法です。

またこちらをあわせて参考にさせて頂きました。

Contents

XDM (Cross Document Messaging)

まず、1 つ目の回避方法として、iframe と (HTML 5 の) postMessage を使った Cross Document Messaging による解決方法です。

この方法は、ブラウザー上のページ (iframe) を使用して連携するため、ページ自体をセキュアにしておくことで、Microsoft Account、Google、facebook、Twitter、mixi など、現在のインターネットで主流となっているクレームベースの認証 (SAML, OpenID など) と相性良く、セキュアに利用できます。このため、例えば、SharePoint や Lync など Office サーバー製品や、JavaScript 用の Facebook SDK など、主に認証を必要とする場合にこの方式が採用されています。

インラインフレームの Window オブジェクトには、HTMLIFrameElement.contentWindow プロパティでアクセスする。

メッセージを送信するには、window.postMessage を利用する。

CORS (Cross-Origin Resource Sharing)

その他の回避方法として、さらにブラウザー依存性が高くなりますが、同じく HTML 5 の仕様を使った Cross-Origin Resource Sharing (CORS) があります。
これは、ブラウザーとサーバー間で、約束された Request / Response を使って、そのドメインからのクロスドメインの呼び出しを許可するか確認をおこない、もしサーバーが許可していれば XMLHttpRequest を使用したクロスドメインの呼び出しをおこないます。

この方法の最大のメリットは、他と方法と比べもっとも自然な方法である という点です。(他の 2 つの方法は、本来、Cross Domain 接続をするために用意された技術ではありません。) このため、将来、ブラウザーのバージョンがあがっていくと、この手法は本命になってくるでしょう。
原則として XMLHttpRequest.open メソッドでは異なるオリジンを指定できない。相対パスを指定する。

サーバが Access-Control-Allow-Origin 応答ヘッダーで明示的に許可していれば可能となる。

Access-Control-Allow-Origin: http://foo.example

IE10以降が必要となる。

JSONP

上述の方法 (1, 2) では、どれも、比較的最近の仕様を使っていました。一方、ここで説明する JSONP を使った回避方法の最大の利点は、Old Browser でも使用できる という点です。このため、広く一般で使用されるようなサービス (例えば、Bing Map、Google Map など) で多く採用されています。ただし、この方法のデメリットもありますので注意してください。(後述しますが、JSONP は、厳格なセキュリティを要求しないような汎用のサービスに向いています。)

サーバー側 (サービス側) で、このような利用が可能となるように構築しておく必要があります。つまり、ブラウザー側 (クライアント側) の勝手な判断だけで このような接続をおこなうことはできません。

また、この方式からわかるように、JSONP では認証 (Authentication) との組み合わせが困難です。さらに、JSONP サービスに情報 (入力データなど) を渡す場合、GET の URI の一部 (query string など) の形で付帯情報を渡す必要がありますが、こうしたデータも、SSL (Https) を使用した暗号化の対象とはなりません。
つまり、以前も記載しましたが、JSONP のサービスは、厳格なセキュリティが不要な一般的なサービス (広く公開可能なサービス) で使用するようにしてください。(例えば、データの更新をおこなうサービスなどには向いていません。セキュアにするために、いろいろと手の込んだ独自の仕掛けが必要です。)

セキュリティ上の理由から、クロスオリジン通信が制限されている。
そのため「クライアントサイドからは、プロキシ経由で外部サービスにアクセスする」という方法をとっていた。

クロスオリジンを乗り越える方法として JSONP が考案された。

  • イベントが発生したタイミングで、外部サーバのスクリプトをインクルードするための <script> 要素を生成する。
  • 外部サーバは <script> 要素を介して、JSON データを含んだ関数呼び出しのコードをクライアントに応答する。
  • 外部サーバからの指示に応じて呼び出されるべき関数をクライアント側に用意し、JSON データを処理する。

その他サンプル。

危険性について

補遺