问题总结

  1. 一般来讲,后端用下面三个方式来解决跨域问题。
    一般来用过滤的方式来解决。
  2. 配置跨域配置后如果还是报错的话,不要急着怀疑跨域配置是否生效。
  1. 看下该接口是否调通
  2. 看下过滤器是否执行(配置中添加log打印看是否打印)
  3. 打断点,查看原因
  1. 跨域问题是浏览器发出请求后,返回的信息被拦截了,额如实请求发不出去。
  2. 跨域并非浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。理解这一点是很重要的。
  3. 报跨域问题不一定是跨域问题,也可能是接口调不通,还可能是接口调通但是返回值被Return掉了,(不是异常)。因此调通了,但是就是跨域异常。

问题解决

问题一

Access to XMLHttpRequest at ‘http://portal.yunjiglobal.com/authority_system/permission/getMenuByworkCodeAndSyst
emId’ from origin ‘http://attendance.yunjiglobal.com’
has been blocked by CORS policy: Request header field contenttype is not allowed by
Access-Control-Allow-Headers in preflight response.
上面中看起来是跨域的问题,报这个错是因为,返回值没有拿到,因此报跨域。但是在代码中发现是因为,这个接口在进行SSO登陆验证中没有传入Cookie,导致该接口没有通过SSO验证,直接被Return掉了,因此没有返回值,因此浏览器拿不到返回值,因此报这个错。

问题二

这个错误是报503,也是跨域的报错。仔细检查发现是重新部署后,项目的端口号改变,也是导致接口调不通,报这个错。

注解跨域

  • springMVC的框架在4.2以上的版本就可以使用注解来实现跨域,在controller的文件上添加@Cross Origin(origins="*")支持所有的跨域

过滤跨域

  • 代码
@Slf4j
//@Component
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");

        //response.setHeader("Access-Control-Allow-Headers", "Content-Type,x-token,ticket,Accept,Accept-Encoding,Accept-Language,Connection,Content-Length,Host,Origin,User-Agent");
        response.setHeader("Access-Control-Allow-Headers", "*");

        response.setHeader("Access-Control-Allow-Headers", "Content-Type,x-token,ticket,Accept,Accept-Encoding,Accept-Language,Connection,Content-Length,Host,Origin,User-Agent");
        //response.setHeader("Access-Control-Allow-Headers", "*");


        response.setHeader("Access-Control-Expose-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        log.info("*********************************过滤器被使用**************************");


        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}
  • 拦截器实现了之后就需要在web.xml中配置,使拦截器发挥效果
<filter>
     <filter-name>cors</filter-name>
     <filter-class>xxx.xxxx.HeadersCORSFilter</filter-class><!--过滤器路径-->
</filter>
<filter-mapping>
     <filter-name>cors</filter-name>
     <url-pattern>/url/*</url-pattern><!--接口前缀-->
</filter-mapping>

这个web配置,需要测试下。

CorsConfig 配置

@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 允许任何域名使用
        corsConfiguration.addAllowedHeader("*"); // 允许任何头
        corsConfiguration.addAllowedMethod("*"); // 允许任何方法(post、get等)
        corsConfiguration.setAllowCredentials(true); //是否支持安全证书
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }
}

CorsConfigration 配置

//@Configuration
@Slf4j
public class CorsConfigration implements WebMvcConfigurer{
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
   @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins(request.getHeader("origin"))
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("Content-Type,x-token,ticket,Accept,Accept-Encoding,Accept-Language,Connection,Content-Length,Host,Origin,User-Agent");
        log.info("CorsConfigration配置执行11");
    }
}