分享

Spring boot跨域设置

 WindySky 2017-12-11

1. 原由

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


2. 使用场景

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

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


3.解决方案

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


4. 具体解决

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

  1. @Configuration  
  2. public class CorsConfig {  
  3.     private CorsConfiguration buildConfig() {  
  4.         CorsConfiguration corsConfiguration = new CorsConfiguration();  
  5.         corsConfiguration.addAllowedOrigin("*"); // 1  
  6.         corsConfiguration.addAllowedHeader("*"); // 2  
  7.         corsConfiguration.addAllowedMethod("*"); // 3  
  8.         return corsConfiguration;  
  9.     }  
  10.   
  11.     @Bean  
  12.     public CorsFilter corsFilter() {  
  13.         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
  14.         source.registerCorsConfiguration("/**", buildConfig()); // 4  
  15.         return new CorsFilter(source);  
  16.     }  
  17. }  

后来改为Filter方式

  1. @Component  
  2. public class CorsFilter implements Filter {  
  3.   
  4.     final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);  
  5.   
  6.   
  7.   
  8.     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
  9.         HttpServletResponse response = (HttpServletResponse) res;  
  10.   
  11.         HttpServletRequest reqs = (HttpServletRequest) req;  
  12.   
  13.         response.setHeader("Access-Control-Allow-Origin","*");  
  14.         response.setHeader("Access-Control-Allow-Credentials", "true");  
  15.         response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  
  16.         response.setHeader("Access-Control-Max-Age", "3600");  
  17.         response.setHeader("Access-Control-Allow-Headers", "x-requested-with");  
  18.         chain.doFilter(req, res);  
  19.     }  
  20.     public void init(FilterConfig filterConfig) {}  
  21.     public void destroy() {}  
  22. }  

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

  1. <span style="color:#ff0000;">Fetch API cannot load https://atfcapi.alpha./atfcapi/project/mainPageList. The value of the 'Access-Control-Allow-Origin' </span>  
  1. <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.' is therefore not allowed access.</span>  

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

  1. response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test.faas.");  
这样设置就成功了,但是我们有好几个环境,同一套代码,写死一个域名并解决不了问题,

按照很多网络文章中所说,设置多个域名如下:

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

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

  1. <span style="color:#ff6666;">Fetch API cannot load https://atfcapi.alpha./atfcapi/project/getProjects. The 'Access-Control-Allow-Origin' header contains multiple values </span>  
  1. <span style="color:#ff6666;">'https://atfcapi-test.faas.,https://atfcapi-test-beta.faas.', but only one is allowed. Origin 'https://atfcapi-test.faas.' 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>  

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

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

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

  1. @Component  
  2. public class CorsFilter implements Filter {  
  3.   
  4.     final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);  
  5.   
  6.   
  7.   
  8.     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
  9.         HttpServletResponse response = (HttpServletResponse) res;  
  10.   
  11.         HttpServletRequest reqs = (HttpServletRequest) req;  
  12.   
  13.         response.setHeader("Access-Control-Allow-Origin",reqs.getHeader("Origin"));  
  14.         response.setHeader("Access-Control-Allow-Credentials", "true");  
  15.         response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  
  16.         response.setHeader("Access-Control-Max-Age", "3600");  
  17.         response.setHeader("Access-Control-Allow-Headers", "x-requested-with");  
  18.         chain.doFilter(req, res);  
  19.     }  
  20.     public void init(FilterConfig filterConfig) {}  
  21.     public void destroy() {}  
  22. }  

从request 中的header中获取Origin,来做配置,最终成功并满足需求。

其实有些东西还是一知半解,但是起码曲线救国也是一种解决方法。




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多