一個是MVC 一個是WEB API html
問題描述web
當跨域(cross domain)調用ASP.NET MVC或者ASP.NET Web API編寫的服務時,會發生沒法訪問的狀況。ajax
重現方式api
【備註】一樣的狀況,也發生在ASP.NET MVC中。某些時候,MVC也能夠直接用來開發服務,與WebAPI相比各有優缺點。下面是一個利用MVC開發的服務的例子跨域
緣由分析瀏覽器
跨域問題僅僅發生在Javascript發起AJAX調用,或者Silverlight發起服務調用時,其根本緣由是由於瀏覽器對於這兩種請求,所給予的權限是較低的,一般只容許調用本域中的資源,除非目標服務器明確地告知它容許跨域調用。安全
因此,跨域的問題雖然是因爲瀏覽器的行爲產生出來的,但解決的方法倒是在服務端。由於不可能要求全部客戶端下降安全性。服務器
解決方案框架
針對ASP.NET MVC和ASP.NET Web API兩種項目類型,我作了一些研究,肯定下面的方案是可行的。less
針對ASP.NET MVC,只須要在web.config中添加以下的內容便可
<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" />
</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>
針對ASP.NET Web API,除了上面這樣的設置,還須要添加一個特殊的設計,就是爲每一個APIController添加一個OPTIONS的方法,但無需返回任何東西。
public string Options()
{
return null; // HTTP 200 response with empty body
}
2:如何設置路由
個人Web.API路由問題。我有如下兩條路線:
config.Routes.MapHttpRoute(
name: "MethodOne",
routeTemplate: "api/{controller}/{action}/{id}/{type}", defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "MethodTwo", routeTemplate: "api/{controller}/{action}/{directory}/{report}", defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional } );
在個人控制器這兩個方法:
[HttpGet]
[ActionName("methodone")]
public string MethodOne(string id, string type) { return string.Empty; } [HttpGet] [ActionName("methodtwo")] public string MethodTwo(string directory, string report) { return string.Empty; }
我用的最笨的方法,每一個action 都註冊了一個路由
別忘記默認路由不要註釋
ajax post沒有問題,多個GET方法,options過不去。顯示Response for preflight has invalid http status code 405
在global中處理下option
protected void Application_BeginRequest() { if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") { Response.End(); } }
另外,還要注意header的設定。多個容許的自定義header逗號隔開。否則也會被拒絕。
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type,Token" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /> </customHeaders> </httpProtocol>
若是還有不明白 請參考下面三個
引用 文件 https://www.cnblogs.com/chenxizhang/p/3821703.html
https://www.cnblogs.com/stoneniqiu/p/9034535.html
http://www.voidcn.com/article/p-avezrrbv-btd.html