【筆記】Asp.Net WebApi對js POST帶參數跨域請求的支持方案

先說下需求:在原來的WebApi項目中增長對js跨域的請求支持,請求方式:以POST爲主,webapi路由規則根據原項目需求修改以下:html

public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

熟悉WebApi的猿猿們都知道這樣設置路由規則直接致使了同一個controller中的不一樣方法的訪問改由方法前的標籤決定,而不是方法名來決定。web

關於js跨域的原理以下:假設咱們請求的地址A:http://api.xx.com/api/GetAllPeople,那若是在B頁面 http://www.baidu.com/tlzzu.html中使用POST去調用外部接口的話,B頁面會先向A地址發送一個OPTIONS類型(OPTIONS並非webapi中的一個方法名,而是一種請求類型,相似POST、GET等)的預檢請求(Preflight Request)只要對這種請求返回200就能夠,具體內容不做檢驗。執行成功後會再次對A接口進行正常請求。返回數據。ajax

解決辦法:json

若是是Asp.Net MVC或者是WebApi可進行以下設置:api

1.先在Web.config中進行以下設置:跨域

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Origin,X-Requested-With,Content-Type,accept,key" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

注意【Access-Control-Allow-Headers】屬性,裏面表示iis容許接受的headers的集合,若是沒有key則不能在JQuery.ajax中使用beforeSend(或者headers:{"key":"11111"},)方法傳遞參數.若是在HTTP請求中會在請求頭裏加入其它屬性,則必定要在app

<add name="Access-Control-Allow-Headers" value="Origin,X-Requested-With,Content-Type,accept,key" />cors

中聲明。
測試

2.在Global.asax文件中設置:jsonp

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            var req = System.Web.HttpContext.Current.Request;
            if (req.HttpMethod == "OPTIONS")//過濾options請求,用於js跨域
            {
                Response.StatusCode = 200;
                Response.SubStatusCode = 200;
                Response.End();
            }
        }

用於過濾全部的OPTIONS請求

3.在B頁面中進行以下請求:

$.ajax({
    type: "POST",
    contentType: "application/x-www-form-urlencoded",
    url: "http://api.xx.com/api/GetAllPeople",
    dataType: "json",
    data:{DM:52,key:"11111"},
    success: function (result) {
        alert(JSON.stringify(result));
    }
});

總結:

遇到問題是須要冷靜,建立demo測試的時候demo須要乾淨,最好全過程從新建立。

另:

1.聽說在apicontroller上添加[EnableCors]屬性也能夠進行跨域訪問,不過我沒找到,可參考下面文章:ASP.NET Web API自身對CORS的支持: EnableCorsAttribute特性背後的故事

2.jsonp方式的請求只支持GET方式的請求,因此不能知足如今的須要(帶參數的POST跨域請求);

3.本文還參考關於AJAX跨域調用ASP.NET MVC或者WebAPI服務的問題及解決方案文章

相關文章
相關標籤/搜索