springboot跨域訪問(wèn)cros與@CrossOrigin注解詳析
一、url
url(uniform resource locator:統(tǒng)一資源定位符)
協(xié)議://域名:端口號(hào)/資源路徑/文件名
二、同源的含義
所謂同源,就是指請(qǐng)求的資源url和目前文件來(lái)源url的協(xié)議、域名和端口都相同。同源即同域,兩者意思相同。
舉例:網(wǎng)址:http://www.oneRound.com/dir/page.html ,它的協(xié)議是http://,域名是www.oneRound.com ,端口是80(http協(xié)議在沒(méi)有指定端口號(hào)時(shí),默認(rèn)端口號(hào)是80)。
將表格中的url與 http://www.oneRound.com/dir/page.html 比較判斷是否同源
| url | 是否同源 | 原因 |
|---|---|---|
| http://www.oneRound.com/dir/page/index.html | 是 | 資源路徑和文件名不同,但三要素相同 |
| http://www.round.com/dir/page.html | 否 | 域名不同 |
| https://www.oneRound.com/dir/page.html | 否 | 協(xié)議和端口號(hào)都不同(http協(xié)議的默認(rèn)端口號(hào)為80,https協(xié)議的默認(rèn)端口號(hào)為443) |
| http://www.oneRound.com:8080/dir/page.html | 否 | 端口號(hào)不同(端口號(hào)不寫(xiě)時(shí),端口號(hào)為該協(xié)議默認(rèn)的端口號(hào)) |
三、瀏覽器的同源策略
瀏覽器的同源策略是指:js腳本在未經(jīng)允許的情況下,不能夠訪問(wèn)其他域下的內(nèi)容,以保證用戶信息的安全,防止惡意的網(wǎng)站竊取數(shù)據(jù)。
同源策略主要限制:
1、一個(gè)域下的js腳本不能訪問(wèn)另一個(gè)域下面的cookie,localStorage和indexDB
2、一個(gè)域下的js腳本不能夠操作另一個(gè)域下的DOM
3、ajax不能做跨域請(qǐng)求
1、限制cookie 等信息的跨源網(wǎng)頁(yè)讀取,為了防止惡意網(wǎng)站通過(guò)js獲取用戶其他網(wǎng)站的cookie,是為了保護(hù)本地用戶信息
2、限制dom的操作,因?yàn)閻阂饩W(wǎng)站可以通過(guò)iframe打開(kāi)系統(tǒng)界面,如果可以獲取DOM就相當(dāng)于可以獲取整個(gè)系統(tǒng)界面的信息。
3、限制跨域 ajax 請(qǐng)求,是為了保護(hù)被跨域請(qǐng)求的服務(wù)器中數(shù)據(jù)庫(kù)用戶信息,更加準(zhǔn)確地說(shuō)是跨域請(qǐng)求能發(fā)出去,服務(wù)器端能收到請(qǐng)求并正常返回結(jié)果,但是結(jié)果被瀏覽器攔截了
特殊:script標(biāo)簽,img標(biāo)簽,以及l(fā)ink標(biāo)簽可以鏈接其他域中的資源, 因?yàn)檫@些標(biāo)簽不能通過(guò)相應(yīng)的結(jié)果來(lái)進(jìn)行安全問(wèn)題的操作。
四、跨域訪問(wèn)
1、什么是跨域訪問(wèn)
從 A 向 B 發(fā)請(qǐng)求,如果他們的url非同源,直接訪問(wèn)就會(huì)造成跨域問(wèn)題??缬蚴强蛻舳藛?wèn)題,跨域請(qǐng)求有兩種情況:
①普通的圖片、css文件請(qǐng)求,不報(bào)錯(cuò)
②發(fā)送Ajax請(qǐng)求,報(bào)錯(cuò)
發(fā)起跨域請(qǐng)求 --> 瀏覽器在請(qǐng)求的header上添加origin字段 --> 請(qǐng)求成功發(fā)送到服務(wù)器 --> 服務(wù)器將數(shù)據(jù)返回給瀏覽器 --> 服務(wù)器返回的響應(yīng)頭中,沒(méi)有告訴瀏覽器哪個(gè)域名可以訪問(wèn)這些數(shù)據(jù)(沒(méi)有設(shè)置 Access-Control-Allow-Origin)--> 瀏覽器將丟棄數(shù)據(jù),拋出錯(cuò)誤
2、為什么前后端分離項(xiàng)目會(huì)產(chǎn)生跨域問(wèn)題
前后端分離的應(yīng)用,前端、后端是2個(gè)獨(dú)立的應(yīng)用,運(yùn)行在不同端口。在瀏覽器看來(lái),是不同的域,由于瀏覽器同源策略的限制,導(dǎo)致不同源之間的通信。前端頁(yè)面中的ajax請(qǐng)求后端接口,即跨域訪問(wèn)。
3、跨域過(guò)程分析
瀏覽器對(duì)前端頁(yè)面和后臺(tái)交互url判斷,若同源,則直接發(fā)送數(shù)據(jù)請(qǐng)求;若不同源,則發(fā)送跨域請(qǐng)求 ---->
判斷跨域請(qǐng)求。非簡(jiǎn)單請(qǐng)求:瀏覽器會(huì)幫我們自動(dòng)觸發(fā)預(yù)檢請(qǐng)求,用于確認(rèn)請(qǐng)求內(nèi)容是否符合服務(wù)端的要求,如果符合,在進(jìn)行正式的請(qǐng)求。簡(jiǎn)單請(qǐng)求:直接發(fā)出正常請(qǐng)求。---->
服務(wù)器收到瀏覽器跨域請(qǐng)求后,根據(jù)自身配置返回對(duì)應(yīng)文件頭。若未配置允許跨域,即文件頭里不包含 Access-Control-Allow-origin 字段,若配置過(guò)域名,則返回 Access-Control-Allow-origin + 對(duì)應(yīng)配置規(guī)則里的域名的方式。 ---->
瀏覽器根據(jù)接收到的響應(yīng)頭里的 Access-Control-Allow-origin 字段判斷,若無(wú)該字段,說(shuō)明不允許跨域,拋出一個(gè)錯(cuò)誤;若有該字段,對(duì)字段內(nèi)容和當(dāng)前域名做比對(duì),如果同源,即允許跨域,瀏覽器接受該響應(yīng);若不同源,即該域名不可跨域,瀏覽器不接受該響應(yīng),并拋出一個(gè)錯(cuò)誤。
cros跨域請(qǐng)求之簡(jiǎn)單請(qǐng)求、復(fù)雜請(qǐng)求
簡(jiǎn)單請(qǐng)求:
簡(jiǎn)單請(qǐng)求的內(nèi)容:
請(qǐng)求方法:get、post、head
HTTP的頭信息不超出以下幾種:Accept 、Accept-Language、Content-Language、
Content-Type
Content-Type的值只有以下三種:text/plain、multipart/form-data、application
請(qǐng)求中的任意XMLHttpRequestUpload 對(duì)象均沒(méi)有注冊(cè)任何事件,XMLHttpRequestUpload對(duì)象可以使用 XMLHttpRequest.upload 屬性訪問(wèn)
請(qǐng)求中沒(méi)有使用 ReadableStream 對(duì)象
簡(jiǎn)單請(qǐng)求的部分響應(yīng)頭如下:
1.Access-Control-Allow-Origin(必含)- 不可省略,否則請(qǐng)求按失敗處理。該項(xiàng)控制數(shù)據(jù)的可見(jiàn)范圍,如果希望數(shù)據(jù)對(duì)任何人都可見(jiàn),可以填寫(xiě)"*"。
2.Access-Control-Allow-Credentials(可選) – 該項(xiàng)標(biāo)志著請(qǐng)求當(dāng)中是否包含cookies信息。與請(qǐng)求時(shí)的withCredentials屬性保持一致。
3.Access-Control-Expose-Headers(可選) – 該項(xiàng)確定XmlHttpRequest2對(duì)象當(dāng)中g(shù)etResponseHeader()方法所能獲得的額外信息。通常情況下,getResponseHeader()方法只能獲得如下的信息: Cache-Control 、Content-Language、 Content-Type、Expires、 Last-Modified 、Pragma 當(dāng)你需要訪問(wèn)額外的信息時(shí),就需要在這一項(xiàng)當(dāng)中填寫(xiě)并以逗號(hào)進(jìn)行分隔。
復(fù)雜請(qǐng)求:
復(fù)雜請(qǐng)求的內(nèi)容:
先發(fā)送一次“預(yù)請(qǐng)求”,瀏覽器會(huì)詢問(wèn)服務(wù)器,當(dāng)前所在的網(wǎng)頁(yè)是否在服務(wù)器允許訪問(wèn)的范圍內(nèi),以及可以使用哪些HTTP請(qǐng)求方式和頭信息字段,只有得到肯定的回復(fù),才會(huì)進(jìn)行正式的HTTP請(qǐng)求。預(yù)請(qǐng)求以O(shè)PTIONS形式發(fā)送,當(dāng)中同樣包含Origin,并且還包含了兩項(xiàng)CORS特有的內(nèi)容:
Access-Control-Request-Method – 該項(xiàng)內(nèi)容是實(shí)際請(qǐng)求的種類(lèi),可以是GET、POST之類(lèi)的簡(jiǎn)單請(qǐng)求,也可以是PUT、DELETE等等。
Access-Control-Request-Headers – 該項(xiàng)是一個(gè)以逗號(hào)分隔的列表,當(dāng)中是復(fù)雜請(qǐng)求所使用的頭部。
復(fù)雜請(qǐng)求的預(yù)請(qǐng)求的響應(yīng)頭如下:
1.Access-Control-Allow-Origin(必含) – 和簡(jiǎn)單請(qǐng)求一樣的,必須包含一個(gè)域。
2.Access-Control-Allow-Headers -- 可以返回所有支持的頭部。
3.Access-Control-Allow-Credentials(可選) – 和簡(jiǎn)單請(qǐng)求當(dāng)中作用相同
4.Access-Control-Allow-Methods(必含) – 這是對(duì)預(yù)請(qǐng)求當(dāng)中Access-Control-Request-Method的回復(fù),這一回復(fù)將是一個(gè)以逗號(hào)分隔的列表。盡管客戶端或許只請(qǐng)求某一方法,但服務(wù)端仍然可以返回所有允許的方法,以便客戶端將其緩存。
5.Access-Control-Max-Age(可選) – 以秒為單位的緩存時(shí)間。Access-Control-Max-Age這個(gè)響應(yīng)首部表示 preflight request (預(yù)檢請(qǐng)求)的返回結(jié)果(即 Access-Control-Allow-Methods 和Access-Control-Allow-Headers 提供的信息) 能夠被緩存的最長(zhǎng)時(shí)間,單位是秒。
本塊內(nèi)容原文鏈接:https://blog.csdn.net/qq_36582776/article/details/123670373
五、cros解決跨域訪問(wèn)
注:跨源請(qǐng)求的本質(zhì)是請(qǐng)求別人的信息,所以能否跨域請(qǐng)求,是由被請(qǐng)求的服務(wù)器的設(shè)置決定的。
w3c提出跨域資源共享,CORS機(jī)制 。CORS 是 Cross-Origin-Resource-Sharing 的縮寫(xiě),是一種安全機(jī)制,當(dāng)瀏覽器檢測(cè)到發(fā)送的請(qǐng)求非同源(即跨域)時(shí),會(huì)自動(dòng)在 http 頭部添加一個(gè) origin 字段,解決跨域問(wèn)題的關(guān)鍵就是在服務(wù)端的響應(yīng)頭中設(shè)置Access-Control-Allow-Origin,即可完成跨域數(shù)據(jù)獲取。
在后臺(tái)實(shí)現(xiàn)跨域的設(shè)置,前臺(tái)就可以訪問(wèn)了
當(dāng)瀏覽器發(fā)送一個(gè)跨域請(qǐng)求時(shí)會(huì)在 http 頭部自動(dòng)加上 Origin需要服務(wù)端配合設(shè)置響應(yīng)頭 Access-Control-Allow-Origin:*|Origin 才可完成跨域
六、springboot web項(xiàng)目使用Cros解決跨域
前端的url:http://localhost:8082
后端的url:http://localhost:8086
1、配置全局跨域訪問(wèn)
在項(xiàng)目路徑下創(chuàng)建config文件夾,在config文件夾下創(chuàng)建CrosConfig類(lèi)實(shí)現(xiàn)WebConfigConfigurer

@Configuration
public class CrosConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //**匹配的是我們所有后臺(tái)的路徑,代表后臺(tái)共享了什么資源
.allowedOrigins("http://localhost:8082") //匹配的前臺(tái)的服務(wù)器地址
.maxAge(300 * 1000)
.allowedHeaders("*")
.allowedMethods("*"); //允許的前臺(tái)的請(qǐng)求方式
}
}使用示例:


成功!

2、@CrossOrigin注解
作用:
在controller上添加@CrossOrigin注解用來(lái)開(kāi)啟跨域請(qǐng)求,讓其他域的請(qǐng)求可以訪問(wèn)該controller,否則所有其他域的訪問(wèn)會(huì)全部被拒絕。
詳解:
origin屬性:允許可訪問(wèn)的域列表
maxAge:準(zhǔn)備響應(yīng)前的緩存持續(xù)的最大時(shí)間(以秒為單位)
使用位置:
①類(lèi)

②方法

①@CrossOrigin注解用在類(lèi)上
整個(gè)類(lèi)的方法都可以被允許的域訪問(wèn)
后端controller
@Controller
@CrossOrigin("http://localhost:8082")
//@RequestMapping("/emp")
public class EmpController {
@Autowired
private IEmpService empService;
@RequestMapping("/getConformEmp")
@ResponseBody
public String getConformEmp(@RequestBody Map<String,String> map) {
System.out.println(map);
String name = map.get("name");
String age = map.get("age");
return name + "今年" + age + "歲了!";
}
}
前端(以Vue為例)
methods:{
getInfo(){
this.$http.post("/getConformEmp",{"name":"小明","age":"19"}).then(res => {
this.pInfo = res.data
})
}
}成功!

②注解用在方法上
有注解的方法可以被指定的域訪問(wèn)

跨域訪問(wèn)“/getConformEmp”:成功!

跨域訪問(wèn)“/getConformEmp01”:失敗!

總結(jié)
到此這篇關(guān)于springboot跨域訪問(wèn)cros與@CrossOrigin注解的文章就介紹到這了,更多相關(guān)springboot跨域訪問(wèn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java枚舉類(lèi)型在switch語(yǔ)句正確使用方法詳解
這篇文章主要介紹了Java枚舉類(lèi)型在switch語(yǔ)句正確使用方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
java?-jar啟動(dòng)參數(shù)設(shè)置file.encoding編碼,解決中文亂碼的問(wèn)題
這篇文章主要介紹了java?-jar啟動(dòng)參數(shù)設(shè)置file.encoding編碼,解決中文亂碼的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
mybatis使用foreach遍歷list集合或者array數(shù)組方式
這篇文章主要介紹了mybatis使用foreach遍歷list集合或者array數(shù)組方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
修改Maven settings.xml 后配置未生效的解決
這篇文章主要介紹了修改Maven settings.xml 后配置未生效的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10

