什麼是跨域請求?
假設我們請求的地址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接口進行正常請求。返回數據。
跨域請求的解決方式:
1. 使用JQuery的jsonp(這種方式很簡單,但是隻適合jquery,原生ajax和angularjs並不支持)
2. 通過配置WebApi的Response 響應頭
配置WebApi
如何配置呢?大致分爲二步:
1.修改web.config
2. 重寫Application_BeginRequest方法
修改web.config
如果不新增配置將會報錯:
XMLHttpRequest cannot load [URL]. Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘[URL]’ is therefore not allowed access. The response had HTTP status code 405.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
<add name="Access-Control-Max-Age" value="30" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<!--<remove name="OPTIONSVerbHandler" />-->
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
新增了配置後,部署到IIS中,ajax跨域請求能正常響應,如果是在本機IIS Express時,那麼還需要做第二步操作,重寫Application_BeginRequest方法
重寫Application_BeginRequest
在重寫Application_BeginRequest之前還需要注意一點,在IIS Express中,ajax中的url不能寫http://127.0.0.1:xxx/xxx
應當寫http://localhost:xxx/xxx,否則還會報第一個錯誤。
如果寫法正確,第一步新增web.config也實現了,還會報如下錯誤:
405 Method Not Allowed:XMLHttpRequest cannot load [url]. Response for preflight has invalid HTTP status code 405
那麼請在API的Global.asax新增:
protected void Application_BeginRequest(object sender, System.EventArgs e)
{
var req = System.Web.HttpContext.Current.Request;
if (req.HttpMethod == "OPTIONS")//過濾options請求,用於js跨域
{
Response.StatusCode = 200;
Response.SubStatusCode = 200;
Response.End();
}
}