9、Spring Boot 优雅的实现CORS跨域

前言

咱们的springboot 架手架已经包含了mysql,redis,定时任务,邮件服务,短信服务,文件上传下载,以及docker-compose 构建镜像等等。javascript

接下来让咱们解决另外一个常见的问题。通常的状况下,都是先后端分离的,我这个架手架的初衷也是先后端进行分离,因此这里就涉及到一个很严重的问题啦,当协议,端口,IP三者有其一不一样就会产生跨域,因此须要作跨域支持。css

测试跨域的文件

在这以前,咱们先写一个测试接口是否跨域的html ,这样下面的测试比较方便。html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<link type="test/css" href="css/style.css" rel="stylesheet">

<body>

    <input type="text" style="width:600px;height:30px;font-size:14px;" id="urlText" value="" />
    <br>
    <input type="button" style="margin: 10px";  id="cors" value="判断是否可访问"/>

<p>http://localhost:9090/zlflovemm/</p>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>  
<script type="text/javascript">
    $(function(){
    $("#cors").click(
        function(){
            var url2 = $("#urlText").val();
            $.post({
                contentType:'application/x-www-form-urlencoded;charset=UTF-8',
                url:url2,
                data: "/rAIeKeSBG1LV+XoIq82/O",
                success:function(data){
                    alert("success");
                }
            })
        });
    });
</script>
</body>
</html>

接下来咱们来学习下在springboot 项目中怎么实现支持跨域。java

@CrossOrigin 注解

这种方法是springboot 自带的,使用比较简单,在须要支持的跨域的接口上加上这个注解就能够了。
好比在咱们项目的demo 接口加上注解.就表示这个接口支持跨域,其中origins = "*"
表示全部的地址均可以访问这个接口,也能够写具体的地址,表示只有这个地址访问才能访问到接口。mysql

@CrossOrigin(origins = "*")

file

测试

咱们也来测试一下,启动项目后,在浏览器上运行咱们的测试的html文件。
发现localhost:9090/zlflovemm/ 是能够访问的。
file
说明跨域是支持的。大伙能够先将注解去掉测试一下,而后加上注解测试一下进行对比。jquery

这种方式虽然很简单,可是缺点也不小,须要跨域的接口都须要加上这个注解,这对先后端分离的项目是不友好的,因此这种方式基本上用的不多。linux

重写WebMvcConfigurer的addCorsMappings 方法。

这种方法在实际项目中也用的比较多,是一种全局支持跨域的方法。
咱们建立一个CorsConfig 类。内容以下:git

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")//项目中的全部接口都支持跨域
                .allowedOrigins("*")//全部地址均可以访问,也能够配置具体地址
                .allowCredentials(true)
                .allowedMethods("*")//"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"
                .maxAge(3600);// 跨域容许时间
    }
}

加上@Configuration 表示是配置类,在项目启动的时候会加载。实现WebMvcConfigurer 接口并重写addCorsMappings 方法。代码比较简单,也有注释。程序员

测试的话,你们能够自行测试,我测试都是经过的和上面同样测试就能够,这里就不占篇幅了。github

Filter

除了上面方法外,也可使用过滤器。咱们建立一个CorsFilter 类,内容以下:

@Slf4j
@Component
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.setHeader("Pragma", "no-cache");
        filterChain.doFilter(servletRequest,response);
    }
}

上面代码中设置response.setHeader("Access-Control-Allow-Origin", "*");表示全部的地址均可以访问项目接口。

番外

接下来咱们再介绍一个经常使用的功能,先后端分离,在访问接口的时候,有的 公司每每会增长一下专属的后缀名才能访问。实际上没有什么太大的做用,能稍微增长一下系统的安全性。这里我就简单是实现一下。真个都很是简单。
同样的是实现WebMvcConfigurer 接口,重写configurePathMatch你方法和增长一个dispatcherServlet。

代码以下:

@Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseRegisteredSuffixPatternMatch(true);
    }

    @Bean
    public ServletRegistrationBean servletRegistrationBean(DispatcherServlet dispatcherServlet) {
        ServletRegistrationBean bean = new ServletRegistrationBean(dispatcherServlet);
        bean.addUrlMappings("*.zlf");
        return bean;
    }

这个功能实现,就只用这个多代码,configurePathMatch方法中设置的configurer.setUseRegisteredSuffixPatternMatch(true); 主要是将index 和index.* 都指向咱们controller 中配置的@RequestMapping("/index")。

下面的servletRegistrationBean 方法主要是增长自定义拦截器,只有后缀为“.zlf”的接口才放行。

这样两步就简单的实现了接口增长自定义的后缀名啦。

到此为止,springboot 支持跨域的方式就差很少了,固然还有其余的实现方式没有研究。这些但愿对你们有帮助。

好了,就说这么多啦
代码上传到github:
https://github.com/QuellanAn/...

后续加油♡

欢迎你们关注我的公众号 "程序员爱酸奶"

分享各类学习资料,包含java,linux,大数据等。资料包含视频文档以及源码,同时分享本人及投递的优质技术博文。

若是你们喜欢记得关注和分享哟❤

file

相关文章
相关标签/搜索