クロスドメイン制約 を XmlHttpRequest level 2 で 回避 (プリフライト)

0 件のコメント

クロスドメイン制約 を 回避 する クライアント & サーバー 実装 を XmlHttpRequest level2 の プリフライト を利用して実現します。

クロスドメイン通信 を実現するには "サーバー側" と "クライアント側" の2カ所に対して手を入れる必要があるかどうか考えます。 ここでは、"クライアント側" と "サーバー側" 両方に手を加えて クロスドメイン通信 を実現する方法を載せます。 具体的には、XmlHttpRequest level2 の プリフライト を利用して クロスドメイン通信 を行えるようにします。

サンプルコード の ダウンロード

想定する クロスドメイン通信 環境

サーバーA から HTML & JavaScript を受信し、足りない リソース を サーバーB から取得する環境を想定します。

GET はそのまま通信されますが、POST, PUT, DELETE は プリフライト (OPTIONS) が自動的に行われます。 つまり、自前で OPTIONS を実行しなくても勝手に実行されるので、自動的に行われる プリフライト通信 に正しい応答処理が行われるようにすれば良いことになります。

サーバー 実装

サーバー側では、"プリフライトの応答" と "サービスの実態" の 2つ を記述します。 サーバー側で確認、実装が必要なのでは以下に示す2ファイル(WebApiConfig.cs、CatalogController.cs)です。

以下にサーバー側で必要な実装の内容、手順を載せます。

  1. OPTIONS へのマッピング を確認。
    /App_Start/WebApiConfig.cs
    1
    2
    3
    4
    5
    6
    7
    8
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
  2. プリフライト 用 の コード を 実装。
    /Controllers/CatalogController.cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // OPTIONS api/catalog
    public void Options()
    {
        var response = HttpContext.Current.Response;
     
        response.AppendHeader("Access-Control-Allow-Origin", "http://www.example.com");
        response.AppendHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.AppendHeader("Access-Control-Allow-Headers", "X-PINGOTHER, application/json");
        response.AppendHeader("Access-Control-Max-Age", "1728000");
    }
  3. GET, POST 等 実態 コード を 実装。 (※ここでは POST を サンプルコード として掲載します。その他は、サーバー実装(全体) サンプルコードをご参照ください。)
    /Controllers/CatalogController.cs
    1
    2
    3
    4
    5
    6
    7
    8
    // POST api/catalog
    public string Post([FromBody]string value)
    {
        var response = HttpContext.Current.Response;
        response.AppendHeader("Access-Control-Allow-Origin", "http://www.example.com");
     
        return "success POST method !!";
    }

サーバー実装(全体) サンプルコード

クライアント 実装

クロスドメイン通信 は、実際に行う前に OPTION 通信で クロスドメイン通信 の許可を取った(プリフライト)のち、 はじめて クロスドメイン通信 ができるようになります。 この事前に行われる OPTION通信 は、自前で実装するのではなく、ブラウザの処理で自動的に処理されるようです。 つまり、以下のような処理の流れになります。

  1. クライアントからクロスドメイン通信を試みる
  2. ブラウザが自動で プリフライト (OPTION通信) を行う
  3. クロスドメイン通信ができそうなので、再度リクエストする

実装してみると、以下のような 単純な サンプルコード になります。 これだけで、OPTION と POST が行われます。

1
2
3
4
5
6
7
8
9
10
function () {
    $.ajax({
        type: 'POST',
    }).done(function (data, textStatus, jqXHR) {
        window.alert(JSON.stringify(data));
    }).fail(function (jqXHR, textStatus, errorThrown) {
        window.alert(errorThrown);
    });
};

今回、以下のサイトを参考にしました。

最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!