クロスドメイン制約 を JSONP で 回避 (WCF + jQuery)

0 件のコメント

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

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

※ WCF サービス で JSONP に対応した サービス を実装した場合、コールバック関数名 を指定する パラメター は callback になるようです。 "変更できる" と記載のある記事もありましたが・・・具体的な方法はわかりませんでした。。

※ WCF サービス で RESTful な Web サービス を実現する方法は こちら をご参照ください。

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

まず、サーバー側の実装を行います。 今回、サーバーサイド は "WCF サービス" で実装します。 あらかじめ RESTful WCF サービス を作成してある前提で進めます(詳細は こちら )。 今回のサービスでは、web.config を修正、IService1.csService1.cs を実装します。

  1. web.config を修正します。
    crossDomainScriptAccessEnabled="true" を下記の位置へ追加します。

    web.config

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <services>
          <service name="Service1">
            <endpoint address="Service1" binding="webHttpBinding"
              bindingConfiguration="" contract="IService1" />
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- メタデータ情報の開示を避けるには、展開する前に、下の値を false に設定し、上のメタデータのエンドポイントを削除します -->
              <serviceMetadata httpGetEnabled="true" />
              <!-- デバッグ目的で障害発生時の例外の詳細を受け取るには、下の値を true に設定します。例外情報の開示を避けるには、展開する前に false に設定します -->
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
        <bindings>
          <webHttpBinding>
            <binding crossDomainScriptAccessEnabled="true"></binding>
          </webHttpBinding>
        </bindings>
     </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
     </system.webServer>
      
    </configuration>
    
  2. インターフェース、コントラクト を実装します。

    IService1.cs

    namespace WcfService1
    {
        using System.Runtime.Serialization;
        using System.ServiceModel;
        using System.ServiceModel.Web;
    
        [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            [WebGet]
            Person JsonpTest();
        }
    
        [DataContract]
        public class Person
        {
            [DataMember(Name = "name")]
            public string Name { get; set; }
        }
    }
    
  3. サービス実態 を実装します。

    Service1.cs

    namespace WcfService1
    {
        using System.ServiceModel.Activation;
        using System.ServiceModel.Web;
    
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
        public class Service1 : IService1
        {
            [WebGet(ResponseFormat=WebMessageFormat.Json)]
            public Person JsonpTest()
            {
                return new Person()
                {
                    Name = "hoge"
                };
            }
        }
    }
    

JSONP を リクエストする 実装

次に、クライアント側の実装を行い、テストします。 以下に、 jQuery を用いた JSONP リクエスト の サンプルコード を掲載します。

$.ajax({
    url: 'http://serverb/MvcApplication1/Service/JsonpTest',
    crossDomain: true,
    dataType: 'jsonp'
}).done(function (data, textStatus, jqXHR) {
    $('#result').html(JSON.stringify(data));
}).fail(function (jqXHR, textStatus, errorThrown) {
    window.alert(textStatus);
});

WCF サービス で サーバーサイド を実装した場合、コールバック関数を指定する クエリパラメター は callback で、これは jQuery の デフォルト値 になります。 よって、crossDomaindataType の指定のみで クロスドメイン通信 が実現できます。

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