一、简介
跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的“预检”请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。
跨源 HTTP 请求的一个例子:运行在 https://domain-a.com 的 JavaScript 代码使用 XMLHttpRequest 来发起一个到 https://domain-b.com/data.json 的请求。
出于安全性,浏览器限制脚本内发起的跨源 HTTP 请求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源,除非响应报文包含了正确 CORS 响应头。

二、CORS原理
浏览器将CORS请求分成两类:简单请求 和 非简单请求。
浏览器先根据同源策略对前端页面和后台交互地址做匹配,若同源,则直接发送数据请求;若不同源,则发送跨域请求。
当我们发起跨域请求时,
-
- 如果是非简单请求,浏览器会帮我们自动触发预检请求,也就是 OPTIONS 请求,从而获知服务端是否允许该跨域请求,服务器确认允许之后,才发起实际的 HTTP 请求。
- 如果是简单请求,则不会触发预检,直接发出正常请求。
服务器收到浏览器跨域请求后,根据自身配置返回对应文件头。若未配置过任何允许跨域,则文件头里不包含 Access-Control-Allow-origin 字段,若配置过域名,则返回 Access-Control-Allow-origin + 对应配置规则里的域名的方式。浏览器根据接收到的响应头里的 Access-Control-Allow-origin 字段做匹配,若无该字段,说明不允许跨域,从而抛出一个错误;若有该字段,则对字段内容和当前域名做比对:
-
- 如果同源,则说明可以跨域,浏览器接受该响应;
- 若不同源,则说明该域名不可跨域,浏览器不接受该响应,并抛出一个错误。
三、简单请求与非简单请求
若请求满足所有下述条件,则该请求可视为简单请求:
- 使用下列方法之一:
- 只包含简单HTTP请求头,即
-
- Accept
- Accept-Language
- Content-Language
- Content-Type(需要注意额外的限制)所指定的媒体类型的值仅限于下列三者之一:
-
-
text/plainmultipart/form-dataapplication/x-www-form-urlencoded
-
四、解决跨域请求
1、方案一:在Controller上添加@CrossOrigin注解
@RestController
@RequestMapping(value = "/admin")
@CrossOrigin(allowCredentials = "true" , originPatterns = "*" , allowedHeaders = "*") // maxAge默认值是30min
public class IndexController {
}
弊端:每一个controller类上都来添加这样的一个接口影响开发效率、维护性较差
2、方案二:添加一个配置类配置跨域请求
@Component
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 添加路径规则
registry.addMapping("/**")
// 是否允许在跨域的情况下传递Cookie
.allowCredentials(true)
.allowedOriginPatterns("*")
// 允许请求来源的域规则
.allowedMethods("*")
// 允许所有的请求头
.allowedHeaders("*") ;
}
}
WebMvcConfigurer配置类其实是Spring内部的一种配置方式,采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter。基于java-based方式的spring mvc配置,需要创建一个配置类并实现WebMvcConfigurer 接口。
303

被折叠的 条评论
为什么被折叠?



