赞
踩
在进行web项目开发的时候,前后端分离往往是很常见的开发方式,而说到前后端分离,最常见的问题无非就是跨域了。如何解决跨域问题几乎已经成为了web开发的必修课。本文将提供几种常见的基于springboot的跨域解决思路,鉴于作者水平有限,若有错误,欢迎指正。
@CrossOrigin作为一个强大的注解,特点就是不仅支持在controller中设置,还支持方法级注解。而最简单也最直接的方法,那就是在controller中直接加入。
@CrossOrigin(origins = "*",allowCredentials = "true")
上述方法@CrossOrigin虽然支持单位注解,但是若是要配置全局,未免就太过繁琐了。这时候可以尝试以下三种方法。
通过自定义自己的OriginFilter,实现javax.servlet.Filter接口里的doFilter方法,并声明为Component组件,贴出关键代码如下:
- @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-Methods", "POST, GET, OPTIONS, DELETE,PUT");
- response.setHeader("Access-Control-Max-Age", "3600");
- response.setHeader("Access-Control-Allow-Headers",
- "Origin, X-Requested-With, Content-Type, Accept, " + "X-CSRF-TOKEN");
- response.setHeader("Access-Control-Allow-Credentials","true");
- chain.doFilter(req, res);
- }
使用spring自带的CorsConfiguration解决跨域问题,并使用@Configuration声明为配置类。代码如下:
- @Configuration
- public class CustomCORSConfiguration {
- private CorsConfiguration buildConfig() {
- CorsConfiguration corsConfiguration = new CorsConfiguration();
- corsConfiguration.addAllowedOrigin("*");
- corsConfiguration.addAllowedHeader("*");
- corsConfiguration.addAllowedMethod("*");
- corsConfiguration.setAllowCredentials(true);
- return corsConfiguration;
- }
-
- @Bean
- public CorsFilter corsFilter() {
- UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
- source.registerCorsConfiguration("/**", buildConfig());
- return new CorsFilter(source);
- }
-
- }
在spring2.0中,通过自定义的WebMvcConfigurer可以让我们进一步地自定义自己的web项目,同样的,我们可以在这处理相关的跨域问题。首先,我们需要创建一个配置类,让它继承自WebMvcConfigurationSupport,同时使用@Configuration注解标记该配置类。然后重写它的addCorsMappings即可。代码如下:
- @Configuration
- public class WebMvcConfigurer extends WebMvcConfigurationSupport{
-
- @Override
- protected void addCorsMappings(CorsRegistry registry) {
- registry.addMapping("/**").allowedOrigins("*")
- .allowCredentials(true).allowedMethods("*").maxAge(3600);
- }
- }
此外,还可以在该配置类通过重写addViewControllers方法配置项目启动的首页,以及通过addResourceHandlers方法控制静态资源的请求路径,包括下述的拦截器也可以通过重写这里的addInterceptors方法进行添加。
此外,我们还可以自定义一个拦截器,通过在preHandle中拦截到的HttpServletResponse,对header重新进行设置。对header的设置同方法1,然后再方法3中的WebMvcConfigurer中,通过重写addInterceptors方法添加该拦截器即可。有兴趣的读者可以自行实现。
无论采用上述哪种方式,在进行跨域访问的时候,必须设置withCredentials为true,以jquery为例,ajax请求中须添加
xhrFields: { withCredentials: true },
上述解决方式几乎都是通过重新设置HttpServletResponse的header实现的。其中,关键代码为:
- response.setHeader("Access-Control-Allow-Origin", "*");
- response.setHeader("Access-Control-Allow-Credentials","true");
通过上述方法,可以解决基本的跨域问题。如果你的跨域问题仍得不到解决,可以参考一下我的下一篇博客 新版chrome跨域问题:cookie之SameSite属性,或许对你会有帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。