1、处理个别controller,在controller上使用@CrossOrigin注解即可

@RestController
@RequestMapping("/api")
public class SysController {
@CrossOrigin
@GetMapping("/systime")
public ApiResult sysTime() {
try {
    List<SysTimeVO> sysTimeVOList = sysService.querySysTime();
    return new ApiResult()
        .setSuccess(true)
......

2、全局配置,配置WebMvcConfigurer

@Configuration
public class WebConfig implements WebMvcConfigurer {

// 设置允许跨域请求

@Bean
public WebMvcConfigurer corsConfigurer() {
  return new WebMvcConfigurer() {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
      registry
          .addMapping("/**")
          //            .allowedOrigins("http://yyy.com", "http://xxx.com") //
          // 允许跨域的域名
          .allowedOriginPatterns("*") // 允许所有域
          .allowedMethods("*") // 允许任何方法(post、get等)
          .allowedHeaders("*") // 允许任何请求头
          .allowCredentials(true) // 允许证书、cookie
          .exposedHeaders(HttpHeaders.SET_COOKIE)
          .maxAge(3600L); // maxAge(3600)表明在3600秒内,不需要再发送预检验请求,可以缓存该结果
    }
  };
 }
}

 3、测试

浏览器打开百度,F12调试模式,在console中粘贴如下js代码回车:

var token= "LtSFVqKxvpS1nPARxS2lpUs2Q2IpGstidMrS8zMhNV3rT7RKnhLN6d2FFirkVEzVIeexgEHgI/PtnynGqjZlyGkJa4+zYIXxtDMoK/N+AB6wtsskYXereH3AR8kWErwIRvx+UOFveH3dgmdw1347SYjbL/ilGKX5xkoZCbfb1f0=,LZkg22zbNsUoHAgAUapeBn541X5OHUK7rLVNHsHWDM/BA4DCIP1f/3Bnu4GAElQU6cds/0fg9Li5cSPHe8pyhr1Ii/TNcUYxqHMf9bHyD6ugwOFTfvlmtp6RDopVrpG24RSjJbWy2kUOOjjk5uv6FUTmbrSTVoBEzAXYKZMM2m4=,R4QeD2psvrTr8tkBTjnnfUBw+YR4di+GToGjWYeR7qZk9hldUVLlZUsEEPWjtBpz+UURVmplIn5WM9Ge29ft5aS4oKDdPlIH8kWNIs9Y3r9TgH3MnSUTGrgayaNniY9Ji5wNZiZ9cE2CFzlxoyuZxOcSVfOxUw70ty0ukLVM/78=";
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8080/api/systime');
xhr.setRequestHeader("x-access-token",token);
xhr.send(null);
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

不出现跨域错误即可。

4、配置有自定义拦截器时,在拦截器中获取session校验登录操作时,在拦截器preHandle方法一开始加入:

public class SessionInterceptor implements HandlerInterceptor {

  @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {

    if ("OPTIONS".equals(request.getMethod().toUpperCase())) {
      return true;
    }

    Object obj = request.getSession().getAttribute("customer");
.......

CROS复杂请求时会首先发送一个OPTIONS请求做嗅探,来测试服务器是否支持本次请求,请求成功后才会发送真实的请求;而OPTIONS请求不会携带任何数据,导致这个请求不符合我们拦截器的校验规则被拦截了,直接返回了状态码,响应头中也没携带解决跨域需要的头部信息,进而出现了跨域问题,所以在拦截器中添加options请求处理,遇到options请求全部放行。

前端jquery ajax跨域访问:

$.ajax({
        type: "get",
        url: "http://xxxx.com/apiUser/currentUser",
        data: "",
        dataType: "json",
        xhrFields:{
               withCredentials:true
        }
    });

jquery ajax跨域访问是简单请求,不会做嗅探操作,所以加入withCredentials:true 跨域请求即可,拦截器中的针对options请求的处理针对axios等的嗅探操作。


5、拦截器返回false会引起跨域问题,解决方法是在返回false前添加如下代码:

......
PrintWriter writer = null;
  try {
    writer = response.getWriter();
    response.reset();
    response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
    response.addHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
    response.addHeader("Access-Control-Max-Age", "3600");
    writer.print(json);
  } catch (IOException e) {

  } finally {
    if (writer != null) writer.close();
  }
}
return false;
......