跨域的原因以及解決方案
掃描二維碼
隨時隨地手機(jī)看文章
# 為什么會產(chǎn)生跨域問題
瀏覽器限制,目前所有瀏覽器都實現(xiàn)了同源策略規(guī)范。
請求方式Type為xhr。如果非xhr,如json,script則也不會存在跨域問題
請求方與服務(wù)方的源不同,即跨域,包括:
協(xié)議不同
域名不同
端口不同
同時滿足三個條件才有可能產(chǎn)生跨域問題。
# 解決方案
對于瀏覽器限制的解決方案-關(guān)閉瀏覽器的同源策略檢查
請求方式Type為xhr的解決方案
既然只有Type為xhr的請求才會存在跨域請求,那么我們是不是可以換一種請求方式呢。Jsonp的實現(xiàn)就是這樣。將原本Type是xhr的請求偽造成script請求。
Jsonp的請求路徑后面會自動帶上callback參數(shù),服務(wù)端可據(jù)此判斷是否是jsonp請求,將返回值以script的形式進(jìn)行封裝。且服務(wù)端需要進(jìn)行相應(yīng)的改動。
--args--disable-web-security--user-data-dir
設(shè)置瀏覽器的啟動參數(shù),將瀏覽器的同源策略取消。該方式要求所用的用戶進(jìn)行手動操作,肯定是不現(xiàn)實的。
對于SpringBoot項目
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice{
public JsonpAdvice{
super("callback"); //約定的jsonp請求參數(shù)
}
}
JQuery實現(xiàn)jsonp的原理:
動態(tài)創(chuàng)建一個script,通過這個script去請求,請求完,該script即被銷毀??赏ㄟ^對jQuery打斷點的方式驗證。(可以看到JQuery在網(wǎng)頁源代碼嵌入了一個臨時的script,當(dāng)Jsonp請求完成之后,該Script即被銷毀)
弊端:
服務(wù)器需要改動
只支持GET方式 (因為獲取script都是GET方式,前端指定請求方式也無效,還以GET方式發(fā)起的請求)
3. 對于域不同的解決方案
根據(jù)實際系統(tǒng)架構(gòu)來決定使用哪種方式
被調(diào)用方解決
返回的響應(yīng)頭的包含允許跨域訪問的信息,需要被調(diào)用方進(jìn)行代碼的修改。(可由具體應(yīng)用添加允許跨域信息,也可以由容器,Tomcat,jetty等添加)
通過Filter實現(xiàn)
將允許跨域請求的信息配置在nginx或者apache轉(zhuǎn)發(fā)服務(wù)器
2. 調(diào)用方解決
在調(diào)用方與被調(diào)用方中間再增加一層,該層做轉(zhuǎn)發(fā),將調(diào)用方的請求轉(zhuǎn)發(fā)到被調(diào)用方。其中第一點因為調(diào)用方與該轉(zhuǎn)發(fā)層在同一個域名下,所以不會有跨域問題。第二點,由于不是瀏覽器發(fā)起的請求,所以轉(zhuǎn)發(fā)層調(diào)用被調(diào)用方也是不存在跨域問題的(參見跨域的三要素)。
簡單請求與非簡單請求
當(dāng)瀏覽器發(fā)起一個跨域請求的時候會先判斷是簡單請求還是非簡單請求。
對于簡單請求,瀏覽器會先請求,拿到結(jié)果后再判斷是否跨域。
對于非簡單請求,瀏覽器會先發(fā)起一個預(yù)檢options請求,檢查通過之后再發(fā)起實際的請求。
對于帶cookie的跨域請求,
需要將allowedOrigins設(shè)置為具體的origin,而不能使用
*
。需要設(shè)置響應(yīng)參數(shù)
allowCredentials(true)
,允許帶cookie的跨域
特別推薦一個分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:
長按訂閱更多精彩▼
如有收獲,點個在看,誠摯感謝
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!