欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring boot跨域设置实例详解

程序员文章站 2024-04-01 21:40:46
定义:跨域是指从一个域名的网页去请求另一个域名的资源 1.原由 公司内部有多个不同的子域,比如一个是location.company.com ,而应用是放在app.co...

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

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详解

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