前言
我們的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 = "*")
測試
我們也來測試一下,啟動項目后,在瀏覽器上運行我們的測試的html文件。
發現localhost:9090/zlflovemm/ 是可以訪問的。
說明跨域是支持的。大伙可以先將注解去掉測試一下,然后加上注解測試一下進行對比。
這種方式雖然很簡單,但是缺點也不小,需要跨域的接口都需要加上這個注解,這對前后端分離的項目是不友好的,所以這種方式基本上用的很少。
重寫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,大數據等。資料包含視頻文檔以及源碼,同時分享本人及投遞的優質技術博文。
如果大家喜歡記得關注和分享喲❤