Spring boot跨域设置

2019-11-05 16:32:10

参考地址 Spring boot跨域设置

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里面版本不一致,导致版本冲突或者各种问题


 


@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() {}

}

 


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


 


Fetch API cannot load https://atfcapi.alpha.elenet.me/atfcapi/project/mainPageList. The value of the 'Access-Control-Allow-Origin'

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.

 


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


 


        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");


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


 


 


Fetch API cannot load https://atfcapi.alpha.elenet.me/atfcapi/project/getProjects. The 'Access-Control-Allow-Origin' header contains multiple values

<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,来做配置,最终成功并满足需求。


  • 2020-01-08 23:37:08

    laravel通过图片流返回图片

    我用laravel的字母头像生成框架Laravolt\Avatar生成的base64头像,但我想做个通用但,直接返回图片,我还是根据以往但经验 改写header但返回值为图片返回值,结果返回失败,一堆乱吗,不知道为啥。 后来用了laravel自带但返回图片但方法,结果ok。记录下

  • 2020-01-08 23:45:06

    laravel response 对象一些常用功能点

    通常,我们并不只是从路由动作简单返回字符串和数组,大多数情况下,都会返回一个完整的 Illuminate\Http\Response 实例或 视图。

  • 2020-01-08 23:49:13

    laravel 存储base64格式图片

    一、总结 一句话总结: 二、laravel存储64位图片实例 三、laravel 存储前端上传base64图片 四、php将base64字符串转换为图片

  • 2020-01-09 01:24:28

    mac安装ImageMagick与PHP扩展Imagick

    mac安装ImageMagick和php7.2扩展Imagick,从网上搜索教程,感觉好少,有的教程看起来也很麻烦,不过安装起来,没想到竟然如此简单。不非纯灰之力。

  • 2020-01-09 18:49:17

    pecl安装卸载模块,如何自动配置php.ini

    利用pecl安装php模块,可能需要手工配置php.ini,以加载或禁止相关模块。那么pecl install是不是可以自动配置php.ini呢?答案是肯定的。在pecl isntall的提示信息中,苏南大叔找到了下面的类似提示信息:configuration option "php_ini" is not set to php.ini location。这个设置点,就是本文的关键所在。设置好"php_ini"之后,pecl就可以自动修改php.ini中的extension=了。

  • 2020-01-10 10:23:08

    父元素设置min-height子元素设置100%问题

    父元素设置min-height子元素高度设置100%取不到值,这是因为子元素 div设置 height:100%;只有当父级元素满足min-height:1000px;设置的条件才触发;浏览器默认是不会触发的,所以子元素的100%的高度继承就失效了。min-height 是在 height 计算之后再套用的.

  • 2020-01-10 15:48:46

    Linux下查看文件精确到秒的修改时间

    今天排查一个BUG遇到一个问题,错误日志中打印的时间精确到秒,但当根据日志中的时间去找对应文件进行验证的时候,发现通过 ls -l 或者 ll 命令,都无法查看到文件精确到秒的修改时间。

  • 2020-01-10 15:55:05

    linux php yum 安装Imagick

    通过pecl安装Imagick扩展,成功到是成功了,很顺利,但是so包并不在我当年用yum安装的php7.2的扩展包内,我把生成的Imagick.so,移动到当前用的php包内,并不能用,提示 undefined symbol: spl_ce_Countable)) in Unknown on line 0。