標籤:option eve 問題 tpc ons ted 內容 文檔 mozilla
假設有一簡單架構分為前後兩部分,其一是Angular構成的前端頁面網站,另一個則是通過ASP.NET Web API搭建的後端服務網站。兩個網站因為分別布署,所有會有CORS(Cross-Origin Resource Sharing)的問題。
再假設後端已經對此做好相應配置,比如在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>
那麼當前端調用後端介面:
save(data: any) : Observable<any> { return this.http.post(`${this.apiUrl}`, data) }
後端對應介面內的邏輯理論上應該是能夠被正常執行的:
[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)。
而CORS規範中有兩種類型:
- Simple requests
- Preflighted requests
前者無需額外的處理,但對於內容類型的支援,僅限三種:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
對於除此以外的內容類型,比如application/json,CORS會以預檢請求方式(Preflighted requests)處理。
Preflighted requests要求必須首先使用OPTIONS方法發起一個預檢請求到伺服器,以獲知伺服器是否允許該實際請求。
而在上面的後端服務代碼中並沒有準備相應的處理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)
Web API對application/json內容類型的CORS支援