先說下需求:在原來的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跨域請求);