最近同事詢問他將程式中 enable cors 的程式碼(WebApiConfig.cs's Register method) mark 掉,
config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
然後在 web.config 的 customHeaders 加入允許 cors 的設定
但是 client js 在做 preflight request 時,卻會回 405 Method Not Allowed
原本送出去的 preflight request ,如下,
OPTIONS http://localhost:3304/api/values HTTP/1.1
Accept: */*
Origin: http:// localhost:3304
Access-Control-Request-Method: GET
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: localhost:3304
應該要回,
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/10.0
Public: OPTIONS, TRACE, GET, HEAD, POST
X-AspNet-Version: 4.0.30319
Date: Thu, 09 Mar 2017 05:17:02 GMT
Content-Length: 0
但錯誤的內容卻是 "Message":"要求的資源不支援 http 方法 'OPTIONS'。"
HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Allow: GET,POST
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?
Date: Wed, 08 Mar 2017 08:16:25 GMT
Content-Length: 63
{"Message":"要求的資源不支援 http 方法 'OPTIONS'。"}
疑... 不是在 Header 都加了 Allow-Methods 了嗎?
後來在發現是因為在 web.config 中的 ExtensionlessUrlHandler-Integrated-4.0 handler 設定 ,
它將所有的行為都交給 webapi 去處理了,而程式中會處理 OPTIONS ,
但 mark 掉了之後,就沒人去 handle OPTIONS verb 了,
然後就報錯了 ...
解法可以參考「Supporting the OPTIONS verb in ASP.NET Web API」這篇的方式,
或是在 ExtensionlessUrlHandler-Integrated-4.0 handler 設定中,明確設定要給 webapi 處理的 verbs ,
把 * 改成 GET,HEAD,POST,PUT,DELETE (就看WEBAPI要HANDLE那些),如下,
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*."
verb="GET,HEAD,POST,PUT,DELETE"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
有類似狀況的朋友,可以參考看看哦!
參考資料
Supporting the OPTIONS verb in ASP.NET Web API
ASP.NET Web API - CORS Support in ASP.NET Web API 2
How Extensionless URLs Are Handled By ASP.NET v4
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^