SpringBoot系列(八)分分鐘學會Springboot多種解決跨域方式
SpringBoot系列(八) 分分鐘學會SpringBoot多種跨域解決方式
往期推薦
SpringBoot系列(一)idea新建Springboot專案
SpringBoot系列(二)入門知識
springBoot系列(三)配置檔案詳解
SpringBoot系列(四)web靜態資源配置詳解
SpringBoot系列(五)Mybatis整合完整詳細版
SpringBoot系列(六)整合thymeleaf詳解版
Springboot系列(七) 整合介面文件swagger,使用,測試
** 目錄 **
- 1. 跨域怎麼理解
- 2. SprinBoot中跨域的三種解決方法
- 1. CrossOrigin註解
- 2. 實現WebMvcConfigurer
- 3. 過濾器配置
- 3. 跨域測試
- 4.總結:
1. 跨域怎麼理解
跨域是什麼?
跨域是指不同域名之間的相互訪問,這是由瀏覽器的同源策略決定的,是瀏覽器對JavaScript施加的安全措施,防止惡意檔案破壞。
同源策略:同源策略是一種約定,它是瀏覽器最核心的也是最基本的安全策略,如果缺少了同源策略,則瀏覽器的正常功能可能會受到影響。
所謂同源就是說協議 ,域名,埠號完全一致,有一個不一致就會造成跨域問題。
跨域原理:
- 跨域請求能正常發出去,服務端能接受到請求並正常返回結果,只是結果被攔截了。
- 跨域只存在於瀏覽器,不存在於其他平臺,比如安卓/java/ios等平臺。
- 之所以會發生跨域是因為受到了同源策略的限制,同源策略要求源相同才能進行正常通訊,即協議,域名,埠號都完全一致。
URL :統一資源定位符,它是www的統一資源定位標誌,也就是我們說的網路地址。它的一般格式為:協議型別://伺服器地址:埠號/路徑。
這也就是我們說的跨域中的域。
2. SprinBoot中跨域的三種解決方法
跨域技術CORS:
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
SpringBoot 就對Cross 做了很好的支援。目前有三種跨域方式。
1. CrossOrigin註解
//@CrossOrigin 表示所有的URL均可訪問此資源
@CrossOrigin(origins = "http://127.0.0.1:8093")//表示只允許這一個url可以跨域訪問這個controller
@RestController
@RequestMapping("/testCorss")
public class CorssOriginController {
//可以對方法運用該註解
//@CrossOrigin(origins = "http://127.0.0.1:8093")
@GetMapping("/getString")
public String getString(){
return "跨域成功!";
}
}
程式碼說明:@CrossOrigin這個註解用起來很方便,這個可以用在方法上,也可以用在類上。如果你不設定他的value屬性,或者是origins屬性,就預設是可以允許所有的URL/域訪問。
- value屬性可以設定多個URL。
- origins屬性也可以設定多個URL。
- maxAge屬性指定了準備響應前的快取持續的最大時間。就是探測請求的有效期。
- allowCredentials屬性表示使用者是否可以傳送、處理 cookie。預設為false
- allowedHeaders 屬性表示允許的請求頭部有哪些。
- methods 屬性表示允許請求的方法,預設get,post,head。
2. 實現WebMvcConfigurer
/**
* @author 全棧學習筆記
* @date 2020/4/21 12:04
* @description
*/
public class MyWebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/testCross/**")
.allowedHeaders("*")
.allowedMethods("*")
.allowCredentials(true)
.allowedOrigins("http://localhost:8093")
.maxAge(2000);
}
}
這個沒什麼好說的,就重寫addCorsMappings方法就行,配置好引數,引數和上面的註解的引數類似。這個配置屬於全域性配置,配置好了全部的介面都遵循此規則。上面的註解方式只對類或者方法生效。addMaping是設定對那種格式的URL生效,也就是跟在URL後面的路徑。
3. 過濾器配置
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @author 全棧學習筆記
* @date 2020/4/21 12:49
* @description
*/
@Configuration
public class Filter {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:8093");//*表示允許所有
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config); // CORS 配置對所有介面都有效
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
利用過濾器配置實現跨域,還有另外一種方法
package com.example.democrossorigin.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Configuration
public class CorssFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Credentials", "true");
res.addHeader("Access-Control-Allow-Origin", "http://localhost:8093");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
3. 跨域測試
我們在新建一個SpringBoot web專案,然後在resources 資料夾裡面的static 新建一個index.html
程式碼如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<body>
<div id="test"></div>
<input type="button" value="測試資料" onclick="getString()"/>
</body>
<script>
function getString() {
$.ajax({
url:'http://localhost:8092/testCorss/getString',
type:'get',
data:{},
success:function (msg) {
$("#test").html(msg);
}
})
}
</script>
</html>
我們模擬一個ajax請求,來請求我們的8092埠,執行新的專案結果
點選測試,發起請求
成功從一個專案裡面拿到了另外一個專案的資料,就說明我們的跨域是成功了的。
4.總結:##
本文講述了跨域的產生原因,原理,以及同源策略的概念,然後介紹了在SpringBoot解決跨域的三種方式,分別是利用CrossOrgin註解,全域性配置Mvc,然後就是利用過濾器配置,過濾器有兩種方式,有一種是利用servlet的過濾器實現。如果你覺得本文有用的話!點個贊也不錯哦!你的贊是對我最大的鼓勵和支援