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

相關文章
相關標籤/搜索