赞
踩
前后端跨域问题由浏览器同源策略而来,出现了跨域问题,实际上,请求是可以到达后端控制器内部的,浏览器会因为同源策略将后端返回的结果屏蔽,并向外说明跨域错误。
解决跨域问题的一些方法(不全,后面遇上不同的解决方法再补上,此文持续更新)
1、后端接口或路由方法上添加@CrossOrigin注解
放后端接口上:
放单个路由方法上:
2、在路由方法里的响应体中配置响应头:
ps: 想要哪个控制器里的方法跨域,只需将下面代码复制粘贴到该方法里就行
- HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
- response.addHeader("Access-Control-Allow-Origin","*");
该方法体现了方法1中 @CrossOrigin 注解能实现跨域的本质( @CrossOrigin 注解在内部也是给响应头配置了上面那个参数,但是配置会更详尽一些)
3、写个配置类实现WebMvcConfigurer类,再重写addCorsMappings方法
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
- import org.springframework.web.servlet.config.annotation.CorsRegistry;
-
- @Configuration
- public class CorsConfig implements WebMvcConfigurer {
-
- @Override
- public void addCorsMappings(CorsRegistry registry) {
- registry.addMapping("/**")
- .allowedOrigins("*")
- .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
- .allowedHeaders("*")
- .maxAge(3600);
- }
- }
直接写个配置类实现WebMvcConfigurer类,将上面重写的方法复制粘贴进去就行。附上包名全路径,防导错包。
4、通过给spring注入一个CorsFilter (跨域过滤器)的方法实现
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.cors.CorsConfiguration;
- import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
- import org.springframework.web.filter.CorsFilter;
-
- @Configuration
- public class AA {
- @Bean
- public CorsFilter corsFilter() {
- CorsConfiguration config = new CorsConfiguration();
- config.setAllowCredentials(true);
- // 设置访问源地址
- config.addAllowedOriginPattern("*");
- // 设置访问源请求头
- config.addAllowedHeader("*");
- // 设置访问源请求方法
- config.addAllowedMethod("*");
- // 有效期 1800秒
- config.setMaxAge(1800L);
- // 添加映射路径,拦截一切请求
- UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
- source.registerCorsConfiguration("/**", config);
- // 返回新的CorsFilter
- return new CorsFilter(source);
- }
-
- }
直接写个配置类,然后将AA类里的代码直接原封不动复制粘贴进去就行,更多的配置可以自定义。注意上面特意把导入的包名全路径给了出来,因为容易选错了包,则实现不了效果。
5、引言:前面第1、2种方法肯定不是推荐使用的,因为一个项目中的路由方法很多,1、2种方法需要逐个添加,但是可以把第2种方法改良一下。
思路:写一个拦截器,在拦截器里添加方法2中的代码。
注:“拦截器” 通俗理解,起到了一个钩子的作用,好比后端spring的前置通知、前端vue中vue实例的生命周期中谈的几个钩子函数,没前端浏览器发送的所有请求,在进入控制器里的具体代码之前(包括进入路由映射之前),都会先进入这个叫做 “拦截器” 的东西,我们就是要在 “拦截器” 里用方法2,这样免去了每个路由方法手动配置跨域参数的弊端。
您瞧:
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
-
- @Configuration
- public class CorsConfig implements WebMvcConfigurer {
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- // 增加一个拦截器,可以对拦截请求做一些自定义处理
- registry.addInterceptor(new HandlerInterceptor() {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-
-
- //添加这么一条代码
- response.addHeader("Access-Control-Allow-Origin","*");
-
-
- System.out.println("拦截请求");
- return true;
- }
- })
- // 设置拦截器的过滤路径规则:/** 代码所有请求都拦下来去执行(重写的preHandle方法里的内容)
- .addPathPatterns("/**")
- // 设置不需要拦截的过滤规则:不拦截/admin/login请求
- .excludePathPatterns("/admin/login");
-
- }
- }
这里还有前端配置跨域代理和后端的nginx(反向代理),微服务(配置网关)的方法来解决跨域问题,这里呼应文首的 “文章持续跟新”,遇上了再详细记录。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。