在瞭解SpringBoot使用CROS實現跨域問題之前,我們先聊聊什麼是跨域
?
舉個簡單例子:比如我是中國人,我想出國去另一個國家,但是第一次出國要辦理一系列手續,辦理完手續後才能出國去到另一個國家,這是現實中的跨域問題,同理,作爲開發人員,我們日常的系統資源訪問多多少少也會存在跨域問題,比如我的網站要獲取另一個網站的資源,但是這是兩個不同的站點,這樣我們要獲取所需資源就需要跨域。
爲什麼會有跨域?
說到跨域問題這就不得不說說同源策略,同源策略是瀏覽器的一種安全策略,它用於限制一個origin的文檔或者它加載的腳本如何能與另一個源的資源進行交互。它能幫助阻隔惡意文檔,減少可能被攻擊的媒介。當然這個解釋比較官方,具體可點擊這裏
查看,簡單點就是爲了網絡安全,所謂同源就是兩個網頁協議、域名、端口都相同即是同源,舉個例子如URL:http://store.company.com/dir/page.html
URL | 結果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html | 同源 | 只有路徑不同 |
http://store.company.com/dir/inner/another.html | 同源 | 只有路徑不同 |
https://store.company.com/secure.html | 不同源 | 協議不同 |
http://store.company.com:81/dir/etc.html | 不同源 | 端口不同 ( http:// 默認端口是80) |
http://news.company.com/dir/other.html | 不同源 | 主機不同 |
爲了解決這一問題,前端通常使用JSONP
進行實現,但是JSONP只能發GET
請求,這裏就不多聊了,那麼今天就帶大家聊聊,怎樣在後端通過SpringBootj結合CROS
實現跨域?
更多CROS可以看看阮一峯老師的跨域資源共享 CORS 詳解
SringBoot中使用CROS解決跨域問題
創建兩個SpringBoot項目,分別設置端口爲8080和8081:
cros1項目爲被請求數據的一方,端口爲默認80
編寫請求接口如下:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
此時被請求接口並未做任何處理
cros2項目爲發起數據請求方,端口爲8081
編寫ajax
請求,並訪問http://localhost:8080/hello
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery-1.12.4.js"></script>
</head>
<body>
<div id="msg"></div>
<input type="button" onclick="getData()" value="請求數據">
</body>
<script>
function getData() {
$.get("http://localhost:8080/hello",function (msg) {
$("#msg").text(msg);
})
}
</script>
</html>
在application.properties中修改端口
server.port=8081
編寫完成後,分別啓動兩個項目,通過cors2發起請求:
打開控制檯,點擊請求數據發現會報如下錯誤,No 'Access-Control-Allow-Origin' header is present on the requested resource.
原因是存在跨域,http://localhost:8080/hello這個站點不允許被訪問,那麼,我們對這個接口進行修改如下:
在允許跨域訪問的接口上或類上添加@CrossOrigin
註解,配置origins
允許被訪問的地址
@RestController
public class HelloController {
@GetMapping("/hello")
//在允許跨域訪問的接口上或類上添加@CrossOrigin註解,配置origins允許被訪問的地址
@CrossOrigin(origins = "http://localhost:8081")
public String hello(){
return "hello";
}
}
修改完成後,重啓項目然後再次訪問
跨域問題解決了,但是又衍生出了一個新問題,要是所有的接口都要允許跨域,每個上面都添加@CrossOrigin配置允許訪問的地址,這不是很麻煩嗎,有沒有全局配置?
SpringBoot配置全局CROS
將之前的@CrossOrigin註釋掉,新建配置類WebMvcConfig,如下:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //攔截所有路徑
.allowedOrigins("http://localhost:8081") //允許跨域的地址
.allowedHeaders("*") //允許的頭信息,*表示所有
.allowedMethods("*"); //允許的方法,GET PUT HEAD 等等,* 表示所有
}
}
配置好全局配置後,重新訪問,同樣支持跨域,SpringBoot中使用CROS實現跨域請求就介紹到這裏了。