CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
方法一
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**"). //批量要拦截哪些接口 拦截所有的请求
allowedOrigins("*"). //允许跨域的域名,可以用*表示允许任何域名使用 带有cookie时必须是具体的值,如http://localhost:8080
allowedMethods("*"). //允许任何方法(GET,POST,PUT,DELETE,PATCH,OPTIONS)
allowedHeaders("*"). //允许任何请求头
allowCredentials(false). //允许带上cookie信息
exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); //maxAge(3600)表明在3600秒内,不需要再发送预检验请求,可以缓存该结果
}
}
Access-Control-Allow-Origin
该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
Access-Control-Allow-Credentials
该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
Access-Control-Request-Headers
该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段
Access-Control-Request-Method
该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,可选的GET,POST,PUT,DELETE,PATCH,OPTIONS , *代表所有
Access-Control-Max-Age
该字段可选,用来指定本次预检请求的有效期,单位为秒。如有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。
方法二 xml配置
Spring MVC 从4.2版本开始增加了对CORS的支持在Spring MVC 中增加CORS支持非常简单,可以配置全局的规则
<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="*"
allow-credentials="true"
max-age="1800"
allowed-methods="GET,POST,PUT,DELETE,PATCH,OPTIONS"/>
</mvc:cors>
方法三 自定义拦截器
public class CrossInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
if (request.getHeader(HttpHeaders.ORIGIN) != null) {
String origin = request.getHeader("Origin");
response.addHeader("Access-Control-Allow-Origin", origin);
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT,PATCH, HEAD");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "3600");
}
return true;
}
}
延伸
1.什么是跨域?
跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域
2.为什么浏览器要限制跨域?
原因就是安全问题:如果一个网页可以随意地访问另外一个网站的资源,那么就有可能在客户完全不知情的情况下出现安全问题。比如下面的操作就有安全问题:
用户访问www.mybank.com ,登陆并进行网银操作,这时cookie啥的都生成并存放在浏览器
用户突然想起件事,并迷迷糊糊地访问了一个邪恶的网站 www.xiee.com
这时该网站就可以在它的页面中,拿到银行的cookie,比如用户名,登陆token等,然后发起对www.mybank.com 的操作。
如果这时浏览器不予限制,并且银行也没有做响应的安全处理的话,那么用户的信息有可能就这么泄露了。
3.为什么要跨域?
既然有安全问题,那为什么又要跨域呢? 有时公司内部有多个不同的子域,比如一个是location.company.com ,而应用是放在app.company.com , 这时想从 app.company.com去访问 location.company.com 的资源就属于跨域。
4.实现跨域需要的技术手段。
JSONP或者CORS
SONP不是一门语言,也并不是什么特别开发的技术,它更像是一个BUG,一个开发者找出来可以用来作为跨域传输数据的”漏洞”。虽然名字中带的是JSON,但其实严格来说,传输的javascript代码,只不过代码内容基本都是json而已。
JSONP的原理非常简单,就是HTML标签中,很多带src属性的标签都可以跨域请求内容,比如我们熟悉的img图片标签。同理,script标签也可以,可以利用script标签来执行跨域的javascript代码。通过这些代码,我们就能实现前端跨域请求数据。
最关键的方法是这样的:前端网页中写一个fun1,接受跨域传来的数据并处理。请求的跨域script标签中的代码则是执行这个函数,里面包含跨域的数据:fun1(data)。这样跨域的数据就可以被原有的前端js接受并处理了。
CORS与JSONP的使用目的相同,但是比JSONP更强大。
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。