一、同源策略
- 浏览器为了阻止恶意网站通过ajax请求访问其他网站的敏感数据而设定的同源策略限制
- 同源指发起访问请求的网站和提供资源的网站的以下信息必须一致
- 同源策咯
- 如果发起请求的网站和提供资源的网站不是同源的
- 如果是简单请求
- 请求能发出,服务器也能响应,但浏览器不会将响应数据暴露出来,应用无法获取到数据
- 如果不是简单请求
- 则在发起正式请求之前,会先发起预检请求,请求方法为OPTIONS
- 得到服务器能够支持的操作
- 并与正式请求进行对比,如果满足要求,正式请求才会发出,否则浏览器不会发起请求,而且会提示错误。
二、跨域资源共享
- Cross-Origin Resource Sharing(CORS)
- 大部分浏览器支持CORS
- 简单请求
- 浏览器自动在请求报头中添加“origin”字段,标识发起请求的URL
- 服务器在收到请求后,校验origin,如果校验通过,则在响应报头中添加“Access-Control-Allow-Origin"字段,告知浏览器服务器允许进行跨域请求的网站
- 浏览器将响应报头与请求报头进行比对,进而判断是否允许跨域
- 非简单请求
- 与简单请求相比,非简单请求增加了预检请求,即预先将请求方法和应用设置的请求头发送给服务器
- 请求方法包含在Access-Control-Request-Method中
- 应用添加的请求头包含在Access-Control-Request-Headers中
- 如果服务器校验成功,则在响应头中包含Access-Control-Allow-Headers、Access-Control-Allow-Methods
三、WebApi中的CORS
- 实现条件
- 需要能够处理任意方式的请求,包括GET、OPTIONS等
- 需要提供跨域资源共享的校验策略
- 例如允许跨域操作的action
- 允许发起跨域请求的URL、Header、Method
- WebApi中跨域资源共享的实现
- 利用HttpMessageHandler对请求进行校验
- HttpMessageHandler能处理任意请求,而ActionFilter只在controller激活之后才起作用,对于需要预检的请求来说,一般没有与OPTIONS对应的action
- 利用Attribute提供校验策略
- 可在全局、controller以及action层面进行针对性设置
- 为了能获取到设置在action上的校验策略,需要先将请求方法用Access-Control-Request-Method中的内容进行替换,以匹配到真实的action
- WebApi中的默认实现
- CorsMessageHandler
- 需要调用HttpConfiguration.EnableCors(ICorsPolicyProvider)启用CORS
- 内部实现是将CorsMessageHandler添加到消息管道中
- EnableCorsAttribute
- 对于寄宿在IIS中的WebApi,还需要进行以下设置才能使请求到达服务端应用程序
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>