文章目录
前言
CORS(Cross-origin resource sharing-跨源资源共享)允许网页从其他域向浏览器请求额外的资源,例如 字体,CSS或来自CDN的静态图像。 CORS有助于将来自多个域的网页内容提供给通常具有相同安全策略的浏览器。
叙述
今天在项目开发的时候遇到了一个跨域问题,解决问题以后整理了一下跨域的机制。一起来学习一下。
什么是跨域请求
跨域请求,就是说浏览器在执行脚本文件的ajax请求时,脚本文件所在的服务地址和请求的服务地址不一样。说白了就是ip、网络协议、端口都一样的时候,就是同一个域,否则就是跨域。这是由于Netscape提出一个著名的安全策略——同源策略造成的,这是浏览器对JavaScript施加的安全限制。是防止外网的脚本恶意攻击服务器的一种措施。
同源策略
同源策略[same origin policy]是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。 同源策略是浏览器安全的基石。
什么是源
源[origin]就是协议、域名和端口号。例如:http://www.baidu.com:80这个URL。
什么是同源
若地址里面的协议、域名和端口号均相同则属于同源。
是否是同源的判断
例如判断下面的URL是否与 http://www.a.com/test/index.html 同源
- http://www.a.com/dir/page.html 同源
- http://www.child.a.com/test/index.html 不同源,域名不相同
- https://www.a.com/test/index.html 不同源,协议不相同
- http://www.a.com:8080/test/index.html 不同源,端口号不相同
CrossOrigin属性
Spring MVC提供了@CrossOrigin注解,或者是使用CorsConfiguration。来进行跨域处理。 该标注了注释的方法或类型,允许跨源请求。
origins
- 允许的来源列表. 他的值放置在HTTP协议的响应header的Access-Control-Allow-Origin
- *意味着所有的源都是被允许的。
- 如果未定义,则允许所有来源。
allowedHeaders
- 实际请求期间可以使用的请求标头列表. 值用于预检的响应header Access-Control-Allow-Headers。
- * 意味着允许客户端请求的所有头文件。
- 如果未定义,则允许所有请求的headers。
methods
支持的HTTP请求方法列表。 如果未定义,则使用由RequestMapping注释定义的方法。
exposedHeaders
- 浏览器允许客户端访问的响应头列表。 在实际响应报头Access-Control-Expose-Headers中设置值。
- 如果未定义,则使用空的暴露标题列表。
allowCredentials
- 它确定浏览器是否应该包含与请求相关的任何cookie。
- false – cookies 不应该包括在内。
- “” (空字符串) – 意味着未定义.
- true – 预响应将包括值设置为true的报头Access-Control-Allow-Credentials。
- 如果未定义,则允许所有凭据。
maxAge
- 预响应的高速缓存持续时间的最大时间(以秒为单位)。 值在标题Access-Control-Max-Age中设置。
- 如果未定义, 最大时间设置为1800秒(30分钟).
SpringBoot工程如何解决跨域问题?
方法一:全局配置类
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 1 设置访问源地址
corsConfiguration.addAllowedOrigin("*");
// 2 设置访问源请求头
corsConfiguration.addAllowedHeader("*");
//3 设置访问源请求方法
corsConfiguration.addAllowedMethod("*");
//4 是否允许用户发送、处理 cookie
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//5 对接口配置跨域设置
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
“”代表全部。”**”代表适配所有接口。
其中addAllowedOrigin(String origin)方法是追加访问源地址。如果不使用””(即允许全部访问源),则可以配置多条访问源来做控制。
例如:
corsConfiguration.addAllowedOrigin("http://www.aimaonline.cn/");
corsConfiguration.addAllowedOrigin("http://test.aimaonline.cn/");
查看CorsConfiguration类的官方文档(http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html#addAllowedOrigin-java.lang.String-)
我们可以找到官方对setAllowedOrigins(List allowedOrigins)和addAllowedOrigin(String origin)方法的介绍。
addAllowedOrigin是追加访问源地址,而setAllowedOrigins是可以直接设置多条访问源。
但是有一点请注意,我查看setAllowedOrigins方法源码时发现,源码如下
public void setAllowedOrigins(List<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins != null?new ArrayList(allowedOrigins):null;
}
根据源码可以得知,setAllowedOrigins会覆盖this.allowedOrigins。所以在配置访问源地址时,
addAllowedOrigin方法要写在setAllowedOrigins后面,当然了,一般情况下这两个方法也不会混着用。
方法二:接口上添加注解
例如在接口上使用@CrossOrgin注解:
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@GetMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
方法三:类上添加注解
在整个类上添加注解
@CrossOrigin(allowCredentials = "true",allowedHeaders = "*")
@RestController
@RequestMapping("/account")
public class AccountController {
@GetMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
问题解决
报这个错误的主要原因是我在全局配置类中没有添加cookie的处理。
小结
扩展链接如下:
https://www.cnblogs.com/m4tech/p/7871715.html
官方文档: https://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html#addAllowedOrigin-java.lang.String-
实现跨域的几种不同方式:https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
感谢您的阅读~~