クロスドメイン制約 を JSONP で 回避 (ASP.NET MVC + jQuery)

0 件のコメント

クロスドメイン制約 を 回避 する サーバー実装 を ASP.NET MVC を用いて JSONP で実現します。

クロスドメイン通信 を実現するには "サーバー側" と "クライアント側" の2カ所に対して手を入れる必要があるかどうか考えます。 ここでは、"サーバー側" に手を加えて クロスドメイン通信 を実現する方法を載せます。 具体的には、JSONP形式 で レスポンス を返せるようにすることで、jQuery 等 で クロスドメイン通信 を行えるようにします。

今回は次の図に示すような環境でのクロスドメイン通信を想定し、 この状況でサーバーBにおいて JSONP 形式 で応答する 実装 を載せます。 個人的な趣味趣向の都合で ASP.NET MVC でサンプルコード を作成しています。

JSONP 形式 で 応答する サービス の実装

今回のサービスでは、JsonpHelper.csServiceController.cs を実装します。

  1. JSONP形式 の JavaScriptResult を返す ヘルパー関数 の作成

    JsonpHelper.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    namespace MvcApplication1.Helpers
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.Mvc;
        using System.Web.Script.Serialization;
     
        public static class JsonpHelper
        {
            /// <summary>
            /// 指定されたオブジェクトをシリアル化し、 JSONP (JSON with padding) 形式にシリアル化する
            /// System.Web.Mvc.JavaScriptResult オブジェクトを作成します。
            /// </summary>
            /// <param name="controller">コントローラー</param>
            /// <param name="callback">コールバック関数名</param>
            /// <param name="data">シリアル化対象のオブジェクト</param>
            /// <returns>生成されたスクリプト</returns>
            public static JavaScriptResult Jsonp(this Controller controller, string callback, object data)
            {
                // シリアライザーのインスタンス生成
                var serializer = new JavaScriptSerializer();
     
                // ペイロード部分を生成
                var payload = serializer.Serialize(data);
     
                // JavaScriptResult を生成
                var javascriptResult = new JavaScriptResult()
                {
                    Script = string.Format("{0}({1});", callback, payload)
                };
     
                return javascriptResult;
            }
     
        }
    }
  2. サービス提供する コントローラー の 実装

    ServiceController.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    namespace MvcApplication1.Controllers
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.Mvc;
        using Helpers;
     
        public class ServiceController : Controller
        {
            //
            // GET: /JsonpTest?callback=[callbackName]
     
            public ActionResult JsonpTest(string callback)
            {
                // クライアントへ返すデータ
                var data = new { name = "hoge" };
     
                // JSONP形式 のレスポンスを返却
                return this.Jsonp(callback, data);
            }
        }
    }

JSONP形式 で応答する サービス は使い回す可能性があると考えて、ヘルパー関数 にしました。 ヘルパー関数 (JsonpHelper.cs) 内では、JavaScriptSerializer を利用して オブジェクト から JSON への変換を行っています。 また、レスポンスは JavaScript なので、JavaScriptResult を生成、返却しています。

jQuery で jsonp リクエスト する クライアントスクリプト 実装

上記で実装した サービス に対して リクエスト する クライアント スクリプト の サンプルコード です。

1
2
3
4
5
6
7
8
9
10
11
$.ajax({
    crossDomain: true,
    dataType: 'jsonp'
    //jsonp: 'callback',             // コールバック関数 を指定する クエリパラメター の キー を指定
    //jsonpCallback: 'onjsonpload',  // コールバック関数 を指定する クエリパラメター の 値 を指定
}).done(function (data, textStatus, jqXHR) {
    $('#result').html(JSON.stringify(data));
}).fail(function (jqXHR, textStatus, errorThrown) {
    window.alert(textStatus);
});

上記で実装した サービス において コールバック関数 を指定する クエリパラメター が callback であるため、 サンプルコード では $.ajaxjsonp オプション および jsonpCallback オプション を利用していません。 クエリパラメター を変更する場合、$.ajaxjsonp オプション および jsonpCallback オプション をご参照ください。

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