假設有一簡單架構分爲先後兩部分,其一是Angular構成的前端頁面站點,另外一個則是經過ASP.NET Web API搭建的後端服務站點。兩個站點由於分別佈署,全部會有CORS(Cross-Origin Resource Sharing)的問題。html
再假設後端已經對此作好相應配置,好比在web.config里加上了:前端
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD" /> <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> </customHeaders> </httpProtocol>
那麼當前端調用後端接口:web
save(data: any) : Observable<any> { return this.http.post(`${this.apiUrl}`, data) }
後端對應接口內的邏輯理論上應該是可以被正常執行的:json
[HttpPost] [Route("api/save")] public HttpResponseMessage Save(SomeModel model) { //內部邏輯 }
但結果是出現了Message:"The requested resource does not support http method 'OPTIONS'."
錯誤。後端
產生此問題的緣由在於HttpClient的post方法默認是採用application/json的內容類型(Content-Type)。api
而CORS規範中有兩種類型:bash
前者無需額外的處理,但對於內容類型的支持,僅限三種:服務器
對於除此之外的內容類型,好比application/json,CORS會以預檢請求方式(Preflighted requests)處理。架構
Preflighted requests要求必須首先使用OPTIONS方法發起一個預檢請求到服務器,以獲知服務器是否容許該實際請求。app
而在上面的後端服務代碼中並無準備相應的處理OPTIONS請求的接口,因此纔會有這樣的錯誤。
對應修正方法很簡單,在同一接口方法上加上處理OPTIONS請求的邏輯:
[HttpOptions, HttpPost] [Route("api/save")] public HttpResponseMessage Save(SomeModel model) { if (Request.Method == HttpMethod.Options) return new HttpResponseMessage(HttpStatusCode.OK); //內部邏輯 }
有關CORS的詳細描述,建議參考官方文檔——Cross-Origin Resource Sharing (CORS)