$.ajax 跨域請求 Web Api


      WepApi確實方便好用,沒有配置文件,一個apicontroller直接可以干活了。但今天用$.ajax跨域請求的時候總是獲取不到數據,用fiddler一看確實抓到了數據,但回到$.ajax函數中,直接觸發了error,沒有觸發success,即使狀態碼是200。用apiclient或者瀏覽器直接訪問都是ok的。搜羅一番。最終在這篇文章上面找到答案 。http://code.msdn.microsoft.com/windowsdesktop/Implementing-CORS-support-a677ab5d

原因

     在默認情況下,為防止CSRF跨站偽造攻擊,一個網頁從另外一個域的網頁獲取數據的時候就會受到限制。有一些方法可以突破這個限制,JSONP就是其一。它使用<script> 標簽加一個回調函數。但JSONP 只支持Get方法。而CORS(Cross-Origin Resource Sharing) 跨域資源共享,是一種新的header規范,可以讓服務器端放松跨域的限制,可以根據header來切換限制或不限制跨域請求。它支持所有的Http請求方式。跨域的資源請求帶有一個Http header:Origin,如果服務器支持CORS,響應就會帶有一個header:Access-Control-Allow-Origin ,也有一些特殊的請求。采用 HTTP “OPTIONS” 的方式,hearder中帶有Access-Control-Request-Method或Access-Control-Request-Headers,服務器響應的hearder中需要帶有Access-Control-Allow-Methods,Access-Control-Allow-Headers才行。

實現 

    那怎么實現CORS呢,這用到了Message Handler。它可以在管道中攔截並修改Request,代碼如下:

 public class CorsHandler : DelegatingHandler
    {
        const string Origin = "Origin";
        const string AccessControlRequestMethod = "Access-Control-Request-Method";
        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;
            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    return Task.Factory.StartNew<HttpResponseMessage>(() =>
                    {
                        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                        response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                        string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
                        if (accessControlRequestMethod != null)
                        {
                            response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                        }

                        string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
                        if (!string.IsNullOrEmpty(requestedHeaders))
                        {
                            response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                        }

                        return response;
                    }, cancellationToken);
                }
                else
                {
                    return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
                    {
                        HttpResponseMessage resp = t.Result;
                        resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                        return resp;
                    });
                }
            }
            else
            {
                return base.SendAsync(request, cancellationToken);
            }
        }
    }

然后在Global中加入:

 protected void Application_Start(object sender, EventArgs e)
        {
             GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());
             WebApiConfig.Register(GlobalConfiguration.Configuration);
        }

腳本:

  $.ajax({
               // url: "http://localhost:11576/api/Values",
               url: "http://localhost:39959/api/user/login?name=niqiu&pwd=123456",
               type: "GET",
               //contentType: "application/json;",
                success: function(result) {
                    alert(result.status);
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert("出錯!XMLHttpRequest:" + XMLHttpRequest.status);
                }
            });

 這樣訪問就ok了。

 

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM