定制小程序开发CORS设置跨域不生效排查之路

结构:springboot2.x版本

CORS(定制小程序开发跨域资源共享),定制小程序开发可以把其当做是通过设置http定制小程序开发响应头来允许不同协议、ip、port定制小程序开发可以跨域请求。

在springboot中,定制小程序开发一般常采用两种方式实现CORS:

一,定制小程序开发通过的方式,通过继承WebMvcConfigurationSupport,重写addCorsMappings方法,具体代码如下:

    @Override
     void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
        .allowCredentials(true)
        .allowedHeaders("*")
        .allowedMethods("*")
        .allowedOrigins("*");
        super.addCorsMappings(registry);
  }

二,通过过滤器的方式,具体代码如下:

    @
    public class GlobalCorsConfig {
        @Bean
        public CorsFilter corsFilter() {
            CorsConfiguration config = new CorsConfiguration();
            //开放哪些ip、端口、域名的访问权限,星号表示开放所有域
            config.addAllowedOrigin("*");
            //是否允许发送Cookie信息
            config.setAllowCredentials(true);
            //开放哪些Http方法,允许跨域访问
            config.addAllowedMethod("GET","POST", "PUT", "DELETE");
            //允许HTTP请求中的携带哪些Header信息
            config.addAllowedHeader("*");
            //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
            UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
            configSource.registerCorsConfiguration("/**", config);
            return new CorsFilter(configSource);
        }
  }

接下来,我们对上述两种方式,存在失效情况分别描述:

方式1,可能失效的情况如下:

第一: 如果一个项目中存在多个WebMvcConfigurationSupport或者WebMvcConfigurerAdapter,可能会导致设置的允许跨域addCorsMappings不生效。

第二:如果一个项目中存在多个自定义的拦截器,执行顺序导致设置跨域失效,伪代码如下:

如上,执行顺序是从上至下的,导致业务拦截器先执行,本应该跨域拦截器在业务拦截器前执行。

 

方式2,使用过滤器的方式,我们应该知道过滤器是先与拦截器执行的。所以,这是我们就不要考虑到和拦截器冲突问题。其实,我项目中采用的就是这种方式,过滤器设置CORS允许跨域请求,拦截器处理业务代码(问题出现在拦截器中)。

出现CORS设置不生效时,程序的结构是,存在GlobalCorsConfig的设置就是方式二的设置,然后就是一个业务的拦截器,伪代码如下:

拦截器中代码也很简单,就是验证请求中的key是否合法,合法则不拦截,不合法拦截并响应,代码如下:

也就是采用response流输出的时候,调用了reset()函数,还记得最开头的时候,CORS设置可以简单的理解为对response设置请求头,或者你也会看到另外一种写法,如下:(也是对CORS设置的一种方式)

        HttpServletResponse response = (HttpServletResponse) res;
        String allowedOriginsUrl = configurationUtil.getAllowedOriginsUrl();
        String[] allowedOriginsUrlArr = allowedOriginsUrl.split(",");
        for(String temp : allowedOriginsUrlArr){
            response.setHeader("Access-Control-Allow-Origin",temp); // 允许的来源
        }
        response.setHeader("Access-Control-Allow-Credentials", "true"); // 是否允许证书
        response.setHeader("Access-Control-Allow-Methods", "*"); // 允许的请求方式
        response.setHeader("Access-Control-Max-Age", "3600"); // 预检请求的有效期
        response.setHeader("Access-Control-Allow-Headers", "*");
        chain.doFilter(req, res);

由此,可以更清楚的看出,其实就是response设置了头部header,来实现允许跨域请求。那上面的问题就很明显了,到过滤器的时候,设置了response的响应头允许跨域,但到了拦截器的时候,又把reponse重置了,导致设置的不生效。

 

结论:

1.采用CORS方式,设置允许跨域时,推荐filter的方式,这种方式先于拦截器执行。

2.如果遇到不生效的情况下,我们先采用一种最简单的方式来设置允许跨域,如果可行,放在你项目中不能使用,需要排查是否存在冲突问题了

3.解决跨域还有其他的多种方案(推荐采用代理nginx、网关方式)

 

 

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发