SpringBoot系列(八)分分鐘學會Springboot多種解決跨域方式
- 2020 年 4 月 21 日
- 筆記
- JAVA, springboot, 跨域
SpringBoot系列(八) 分分鐘學會SpringBoot多種跨域解決方式
往期推薦
SpringBoot系列(一)idea新建Springboot項目
Springboot系列(七) 集成接口文檔swagger,使用,測試
** 目錄 **
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 = "//127.0.0.1:8093")//表示只允許這一個url可以跨域訪問這個controller
@RestController
@RequestMapping("/testCorss")
public class CorssOriginController {
//可以對方法運用該註解
//@CrossOrigin(origins = "//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("//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("//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", "//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="//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:'//localhost:8092/testCorss/getString',
type:'get',
data:{},
success:function (msg) {
$("#test").html(msg);
}
})
}
</script>
</html>
我們模擬一個ajax請求,來請求我們的8092端口,運行新的項目結果
點擊測試,發起請求
成功從一個項目裏面拿到了另外一個項目的數據,就說明我們的跨域是成功了的。
4.總結:##
本文講述了跨域的產生原因,原理,以及同源策略的概念,然後介紹了在SpringBoot解決跨域的三種方式,分別是利用CrossOrgin註解,全局配置Mvc,然後就是利用過濾器配置,過濾器有兩種方式,有一種是利用servlet的過濾器實現。如果你覺得本文有用的話!點個贊也不錯哦!你的贊是對我最大的鼓勵和支持。