九、Spring Boot 優雅的實現CORS跨域


前言

我們的springboot 架手架已經包含了mysql,redis,定時任務,郵件服務,短信服務,文件上傳下載,以及docker-compose 構建鏡像等等。

接下來讓我們解決另一個常見的問題。一般的情況下,都是前后端分離的,我這個架手架的初衷也是前后端進行分離,所以這里就涉及到一個很嚴重的問題啦,當協議,端口,IP三者有其一不同就會產生跨域,所以需要做跨域支持。

測試跨域的文件

在這之前,我們先寫一個測試接口是否跨域的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 項目中怎么實現支持跨域。

@CrossOrigin 注解

這種方法是springboot 自帶的,使用比較簡單,在需要支持的跨域的接口上加上這個注解就可以了。
比如在我們項目的demo 接口加上注解.就表示這個接口支持跨域,其中origins = "*"
表示所有的地址都可以訪問這個接口,也可以寫具體的地址,表示只有這個地址訪問才能訪問到接口。

@CrossOrigin(origins = "*")

file

測試

我們也來測試一下,啟動項目后,在瀏覽器上運行我們的測試的html文件。
發現localhost:9090/zlflovemm/ 是可以訪問的。
file
說明跨域是支持的。大伙可以先將注解去掉測試一下,然后加上注解測試一下進行對比。

這種方式雖然很簡單,但是缺點也不小,需要跨域的接口都需要加上這個注解,這對前后端分離的項目是不友好的,所以這種方式基本上用的很少。

重寫WebMvcConfigurer的addCorsMappings 方法。

這種方法在實際項目中也用的比較多,是一種全局支持跨域的方法。
我們創建一個CorsConfig 類。內容如下:

@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 方法。代碼比較簡單,也有注釋。

測試的話,大家可以自行測試,我測試都是通過的和上面一樣測試就可以,這里就不占篇幅了。

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/zlflovemm

后續加油♡

歡迎大家關注個人公眾號 "程序員愛酸奶"

分享各種學習資料,包含java,linux,大數據等。資料包含視頻文檔以及源碼,同時分享本人及投遞的優質技術博文。

如果大家喜歡記得關注和分享喲❤

file


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM