Spring boot跨域设置实例详解

 更新时间:2017年11月14日 11:03:25   作者:yayaqwl  
这篇文章主要介绍了Spring boot跨域设置实例详解,简单介绍了跨域的定义,原因,使用场景及解决方案,具有一定参考价值,需要的朋友可以了解下。

定义:跨域是指从一个域名的网页去请求另一个域名的资源

1.原由

公司内部有多个不同的子域,比如一个是location.company.com ,而应用是放在app.company.com , 这时想从 app.company.com去访问 location.company.com 的资源就属于跨域

本人是springboot菜鸟,但是做测试框架后端需要使用Springboot和前端对接,出现跨域问题,需要设置后端Response的Header.走了不少坑,在这总结一下以备以后使用

2.使用场景

浏览器默认不允许跨域访问,包括我们平时ajax也是限制跨域访问的。

产生跨域访问的情况主要是因为请求的发起者与请求的接受者1、域名不同;2、端口号不同

如果一个网页可以随意地访问另外一个网站的资源,那么就有可能在客户完全不知情的情况下出现安全问题

3.解决方案

通过设置Access-Control-Allow-Origin来实现跨域访问

4.具体解决

刚开始使用http://www.jianshu.com/p/f2060a6d6e3b设置,但是由于我们使用的spring版本的问题,CorsConfiguration类需要4.2.7版本。和我们使用的spring里面版本不一致,导致版本冲突或者各种问题

@Configuration
public class CorsConfig {
  private CorsConfiguration buildConfig() {
    CorsConfiguration corsConfiguration = new CorsConfiguration();
    corsConfiguration.addAllowedOrigin("*"); // 1
    corsConfiguration.addAllowedHeader("*"); // 2
    corsConfiguration.addAllowedMethod("*"); // 3
    return corsConfiguration;
  }

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

后来改为Filter方式

@Component
public class CorsFilter implements Filter {
  final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);

  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest reqs = (HttpServletRequest) req;
    response.setHeader("Access-Control-Allow-Origin","*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
    chain.doFilter(req, res);
  }
  public void init(FilterConfig filterConfig) {}
  public void destroy() {}
}

后来改为Filter方式

@Component
public class CorsFilter implements Filter {
  final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest reqs = (HttpServletRequest) req;
    response.setHeader("Access-Control-Allow-Origin","*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
    chain.doFilter(req, res);
  }
  public void init(FilterConfig filterConfig) {}
  public void destroy() {}
}

网上很多资料都是教按以上方法设置,但是我这里就是设置不成功的。出现下面问题

<span style="color:#ff0000;">Fetch API cannot load https://atfcapi.alpha.elenet.me/atfcapi/project/mainPageList. The value of the 'Access-Control-Allow-Origin' </span> 
<span style="color:#ff0000;">header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'https://atfcapi-test.faas.elenet.me' is therefore not allowed access.</span> 

目前为止,不知道为什么这样配置不可以,然后改为设置单个域名,如下显示

response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test.faas.elenet.me"); 

这样设置就成功了,但是我们有好几个环境,同一套代码,写死一个域名并解决不了问题,
按照很多网络文章中所说,设置多个域名如下:

response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test.faas.elenet.me,https://atfcapi-test-beta.faas.elenet.me"); 

但是设置完以后,并不好用,出现如下错误信息:

<span style="color:#ff6666;">Fetch API cannot load https://atfcapi.alpha.elenet.me/atfcapi/project/getProjects. The 'Access-Control-Allow-Origin' header contains multiple values </span> 
<span style="color:#ff6666;">'https://atfcapi-test.faas.elenet.me,https://atfcapi-test-beta.faas.elenet.me', but only one is allowed. Origin 'https://atfcapi-test.faas.elenet.me' is therefore not allowed access. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.</span> 

设置为以下方式也还是错误:

response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test.faas.elenet.me"); 
    response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test-beta.faas.elenet.me"); 

最后采用了一种和设置为* 的方式一样的办法,代码如下:

@Component
public class CorsFilter implements Filter {
  final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest reqs = (HttpServletRequest) req;
    response.setHeader("Access-Control-Allow-Origin",reqs.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
    chain.doFilter(req, res);
  }
  public void init(FilterConfig filterConfig) {}
  public void destroy() {}
}

从request 中的header中获取Origin,来做配置,最终成功并满足需求。
其实有些东西还是一知半解,但是起码曲线救国也是一种解决方法。

总结

以上就是本文关于Spring boot跨域设置实例详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

快速了解Spring Boot

SpringBoot集成多数据源解析

Maven管理SpringBoot Profile详解

如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • @NonNull导致无法序列化的问题及解决

    @NonNull导致无法序列化的问题及解决

    这篇文章主要介绍了@NonNull导致无法序列化的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • java可变参数当做数组处理的方法示例

    java可变参数当做数组处理的方法示例

    这篇文章主要介绍了java可变参数当做数组处理的方法,结合实例形式分析了java可变参数当做数组处理相关原理、步骤与操作注意事项,需要的朋友可以参考下
    2019-09-09
  • SpringBoot+EasyPoi实现excel导出功能

    SpringBoot+EasyPoi实现excel导出功能

    最新小编遇到这样一个需求,根据检索条件查询列表并将结果导出到excel,实现过程也非常简单,感兴趣的朋友跟随小编一起看看吧
    2021-09-09
  • mybatis多对多关联实战教程(推荐)

    mybatis多对多关联实战教程(推荐)

    下面小编就为大家带来一篇mybatis多对多关联实战教程(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • Spring Boot集成Kafka的示例代码

    Spring Boot集成Kafka的示例代码

    本篇文章主要介绍了Spring Boot集成Kafka的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Java中 shuffle 算法的使用

    Java中 shuffle 算法的使用

    本篇文章,小编将为大家介绍,在Java中 shuffle 算法的使用,有需要的朋友可以参考一下
    2013-04-04
  • mybatisPlus条件构造器常用方法小结

    mybatisPlus条件构造器常用方法小结

    这篇文章主要介绍了mybatisPlus条件构造器常用方法,首先是.select和其他条件,本文结合示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • Java中SPI机制的实现详解

    Java中SPI机制的实现详解

    SPI(Service Provider Interface),是 JDK 内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,下面我们就来看看Java中SPI机制的具体实现
    2024-01-01
  • Spring Boot 中的自动配置autoconfigure详解

    Spring Boot 中的自动配置autoconfigure详解

    这篇文章主要介绍了Spring Boot 中的自动配置autoconfigure详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • Java中的EnumMap集合解析

    Java中的EnumMap集合解析

    这篇文章主要介绍了Java中的EnumMap集合解析,EnumMap是Map接口的一种实现,专门用于枚举类型的键,所有枚举的键必须来自同一个枚举,
    EnumMap不允许键为空,允许值为空,需要的朋友可以参考下
    2023-09-09

最新评论