SpringBoot项目中如何解决跨域问题的最新方案?
作者:清醒的人最荒唐
跨域问题是浏览器为了保护用户的信息安全,实施了同源策略(Same-Origin Policy),即只允许页面请求同源(相同协议、域名和端口)的资源,当 JavaScript 发起的请求跨越了同源策略,即请求的目标与当前页面的域名、端口、协议不一致时,浏览器会阻止请求的发送或接收。
一、同源策略
同源,就是咱们域名、端口号、ip、采用的协议都相同,那么我们就是同源的
反之就是不同源的!!!
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
所以,用最简单的话来说,就是前端可以发请求给服务器,服务器也可以进行响应,只是因为浏览器会对请求头进行判断,所以要么前端设置请求头,要么后端设置请求头
一个域名地址由以下几个部分组成:
http://www.aaa.com:8080/sie=UTF-8&wd=SpringBoot协议:http
域名:子域名www,主域名aaa.com
端口:8080从一个域名的网页去请求另一个域名的资源时,协议,域名,端口任意不同,都会出现跨域问题。
http://www.aaa.com:8080——>http://www.aaa.com:8080:同域访问
http://www.aaa.com:8080——>http://www.bbb.com:8080:跨域访问
二、跨域问题
跨域报错如下:
Access to XMLHttpRequest at 'http://localhost:8080/t1' from origin 'http://localhost:63342' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
test1.html?_ijt=aekdfma33ut4n31cgsohdrjt89:17 {readyState: 0, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
jquery-1.9.1.min.js:5 GET http://localhost:8080/t1 net::ERR_FAILED 200
三、spring boot解决跨域问题
对于 CORS的跨域请求,主要有以下几种方式可供选择:
- 返回新的CorsFilter
- 重写 WebMvcConfigurer
- 使用注解 @CrossOrigin
- 手动设置响应头 (HttpServletResponse)
- 自定web filter 实现跨域
注意:
CorFilter / WebMvConfigurer / @CrossOrigin 需要 SpringMVC 4.2以上版本才支持,对应springBoot 1.3版本以上
上面前两种方式属于全局 CORS 配置,后两种属于局部 CORS配置。如果使用了局部跨域是会覆盖全局跨域的规则,所以可以通过 @CrossOrigin 注解来进行细粒度更高的跨域资源控制。
其实无论哪种方案,最终目的都是修改响应头,向响应头中添加浏览器所要求的数据,进而实现跨域
1、使用CorsFilter
@Configuration public class corsFilter { @Bean public CorsFilter CorsFilter() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOriginPattern("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.setAllowCredentials(true); UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",corsConfiguration); return new CorsFilter(urlBasedCorsConfigurationSource); } }
2、实现WebMvcConfigurer里面的addCorsMappings方法
@Configuration public class corsFilter1 implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 匹配所有的路径 .allowCredentials(true) // 设置允许凭证 .allowedHeaders("*") // 设置请求头 .allowedMethods("GET","POST","PUT","DELETE") // 设置允许的方式 .allowedOriginPatterns("*"); } }
3、@CrossOrigin局部跨域通过
@GetMapping("/t2") @CrossOrigin public Map t2() { HashMap<String, Object> map = new HashMap<>(); User user = new User(); user.setUsername("123456"); user.setPassword("程世玉"); map.put("user",user); return map; }
4、添加响应头解决跨域
@RequestMapping(value = "/user-1") public User getUser_1(HttpServletResponse response ) { // 允许所有,不安全 response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Max-Age", "10"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT"); response.setHeader("Access-Control-Allow-Credentials", "true"); return new User(1L, "Booker", "admin", "sdfsdkjf93hu8dvn"); }
5、使用自定义filter实现跨域
public class MyCorsFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type"); chain.doFilter(req, res); } public void init(FilterConfig filterConfig) {} public void destroy() {} } @Configuration public class FilterConfig { @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new MyCorsFilter()); bean.addUrlPatterns("/*"); return bean; } }
总结
到此这篇关于SpringBoot项目中如何解决跨域问题的最新方案?的文章就介绍到这了,更多相关SpringBoot解决跨域问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!