SpringBoot处理跨域总结

2年前未命名59
SpringBoot处理跨域总结 qq_41084438 已于2023-01-17 15:06:28修改 490 收藏 1 分类专栏: SpringBoot 文章标签: java springboot 跨域 Powered by 金山文档 于2023-01-16 16:30:01首次发布 SpringBoot 专栏收录该内容 20 篇文章 1 订阅 订阅专栏 解决跨域的五种方法 1、CorsFilter

新建一个类

@Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { //1. 添加 CORS配置信息 CorsConfiguration config = new CorsConfiguration(); //放行哪些原始域         //springboot版本为2.4.0以前写法 config.addAllowedOrigin("*");         //springboot版本为2.4.0以后写法         config.setAllowedOriginPatterns(Collections.singletonList("*"));         //查看项目的springboot版本         //System.out.println(SpringBootVersion.getVersion()); //是否发送 Cookie config.setAllowCredentials(true); //放行哪些请求方式 config.addAllowedMethod("*"); //放行哪些原始请求头部信息 config.addAllowedHeader("*"); //暴露哪些头部信息 config.addExposedHeader("*"); //2. 添加映射路径 UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource(); corsConfigurationSource.registerCorsConfiguration("/**",config); //3. 返回新的CorsFilter return new CorsFilter(corsConfigurationSource); } }

2、重写 WebMvcConfigurer @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") //是否发送Cookie .allowCredentials(true) //放行哪些原始域 .allowedOrigins("*") .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"}) .allowedHeaders("*") .exposedHeaders("*"); } }

3、使用注解 @RestController @CrossOrigin(origins = "*") public class CorsController { @RequestMapping("/cors")     @CrossOrigin(origins = "*") public String cors() { return "cors"; } }

4、手动设置响应头 @RequestMapping("/cors") public String cors(HttpServletResponse response) { response.addHeader("Access-Allow-Control-Origin","*"); return "cors"; }

5、使用自定义filter import org.springframework.context.annotation.Configuration; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(filterName = "CorsFilter ") @Configuration public class CorsFilter implements Filter { @Override 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-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT, OPTIONS"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); chain.doFilter(req, res); } }

模拟跨域

跨域的拦截是浏览器行为,所以后端开发的时候不会遇到这个问题,只有在联调的时候才会发现,这种问题前端、后端都可以解决。前端通过代理请求同一域的一个接口,然后转发到后端。后端则通过在Response Header设置值解决。而后端本地测试跨域配置是否生效时比较麻烦,因为是浏览器问题,发布到测试环境流程长,所以需要本地也能复现跨域问题,其实也比较简单,只不过需要百度一些前端代码[狗头]

首先,先随便找一个网站,然后在Console向本地发送Http请求就能模拟跨域了。

// 普通请求 var xhr = new XMLHttpRequest(); xhr.open('OPTIONS', 'http://127.0.0.1:8080/test1'); xhr.send(); xhr.onload = function(e) { var xhr = e.target; console.log(xhr.responseText); } // GET请求 var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://127.0.0.1:8080/test1?a=1'); xhr.send(); xhr.onload = function(e) { var xhr = e.target; console.log(xhr.responseText); } // 携带header var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://127.0.0.1:8080/test1?a=1'); xhr.setRequestHeader('content-type', 'application/json'); xhr.setRequestHeader('signature', 'gaejhgkaehguiaehiuavoihvoihviehviehiohao'); xhr.send(); xhr.onload = function(e) { var xhr = e.target; console.log(xhr.responseText); } // POST请求 var xhr = new XMLHttpRequest(); xhr.open('POST', 'http://127.0.0.1:8080/test1?a=1'); xhr.setRequestHeader('content-type', 'application/json'); xhr.setRequestHeader('signature', 'gaejhgkaehguiaehiuavoihvoihviehviehiohao'); xhr.send("{a:1,b:2}"); xhr.onload = function(e) { var xhr = e.target; console.log(xhr.responseText); }

跨域问题踩过的坑

这些问题主要是网上代码都是抄来抄去,有一些人抄的时候删了一些或者copy漏了,导致代码不全,然后又因为浏览器的一些机制导致了还是存在跨域问题,坑了后面的人。

踩坑一:没有允许OPTIONS请求跨域

比如用上面的方案二来处理跨域问题

乍一看没有什么问题,只是不支持OPTIONS请求,但是浏览器在处理跨域请求的时候,会先发送一个OPTIONS请求去检测服务是否允许跨域请求,然后再去请求服务要数据之类的。所以这里根本没解决,联调时还是会有跨域问题。

踩坑二:没有允许Credentials

场景:后端不允许前端传递用户凭证,但是前端请求的时候带上了,这时浏览器也会报跨域错误

用户凭证是用户登录之后,服务器下发的一些凭证,如cookie。在跨域请求中,浏览器并不会把cookie携带上,但是可以通过js代码携带上。

使用上面方案一,不允许用户凭证

标签: [db:标签TAG]

相关文章

学习python好就业么

学习python好就业么...

python字典中get()函数的用法总结

python字典中get()函数的用法总结...

15000 字的 SQL 语句大全 第一部分

15000 字的 SQL 语句大全 第一部分...

python带你成功复刻热门手机游戏——飞翔的小鸟

python带你成功复刻热门手机游戏——飞翔的小鸟...

学习 Python 之 Pygame 开发魂斗罗(四)

学习 Python 之 Pygame 开发魂斗罗(四)...

一篇文章读懂Android Framework

一篇文章读懂Android Framework...