假设有一简单架构分为前后两部分, 其一是 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) https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
来源: https://www.cnblogs.com/kenwoo/p/8974595.html