1.為什么會出現(xiàn)跨域問題
瀏覽器基于安全性考慮(減少一些攻擊發(fā)生的可能性)不允許非同源(
同源是指協(xié)議、域名奋救、端口三者相同,即使兩個不同的域名指向同一個ip地址也是非同源反惕。主域名相同二級域名不同也為不同源例如 https://abc.com 與https//:www.abc.com
)請求發(fā)生尝艘。
其實雖然瀏覽器報錯,但是實際請求已經(jīng)到了后端層面,只是瀏覽器不允許,攔截了請求
2.解決方案
2.1 jsonp
利用js文件請求不受同源策略限制實現(xiàn),但是只能發(fā)送get請求,并且需要后端配合實現(xiàn),現(xiàn)在基本不使用這種手段
2.2 cors 常用
跨源資源共享標準新增了一組 HTTP 標頭字段姿染,允許服務(wù)器聲明哪些源站通過瀏覽器有權(quán)限訪問哪些資源背亥。另外,規(guī)范要求,對那些可能對服務(wù)器數(shù)據(jù)產(chǎn)生副作用的 HTTP 請求方法(特別是
GET
以外的 HTTP 請求狡汉,或者搭配某些 MIME 類型的POST
請求)娄徊,瀏覽器必須首先使用OPTIONS
方法發(fā)起一個預(yù)檢請求(preflight request),從而獲知服務(wù)端是否允許該跨源請求盾戴。服務(wù)器確認允許之后寄锐,才發(fā)起實際的 HTTP 請求。在預(yù)檢請求的返回中捻脖,服務(wù)器端也可以通知客戶端锐峭,是否需要攜帶身份憑證(例如 Cookie 和 HTTP 認證相關(guān)數(shù)據(jù))。
CORS 請求失敗會產(chǎn)生錯誤可婶,但是為了安全沿癞,在 JavaScript 代碼層面無法獲知到底具體是哪里出了問題。你只能查看瀏覽器的控制臺以得知具體是哪里出現(xiàn)了錯誤矛渴。
后端配置請求頭Access-Control-Allow-Origin 把當前域名添加到上面,則瀏覽器就能正常發(fā)送請求獲得服務(wù)器返回結(jié)果
將請求分為簡單請求與復雜請求
簡單請求不會發(fā)送options預(yù)檢請求,會直接請求 服務(wù)器,服務(wù)器允許則訪問成功,不允許則失敗
復雜請求會先發(fā)送預(yù)檢請求,看服務(wù)器是否允許此次請求,允許發(fā)送真正請求,不允許則請求失敗
2.3 代理
2.3.1反向代理(負載均衡)
通過nginx 在前端所在服務(wù)器加一個nginx對部分請求進行轉(zhuǎn)發(fā),相當于多了一層中間人在傳話,前端工程跟nginx所在服務(wù)器一個域名就不會跨域了
反向代理.png
反向代理 服務(wù)器對用戶不可見,用戶不清楚真正的訪問服務(wù)器那一臺
2.3.2正向代理(vpn)
正向代理就是在本地客戶端建立一個攔截,對于部分請求從本地,直接連接到例如vpn對應(yīng)的服務(wù)器,再由服務(wù)器發(fā)送真正的請求到真實請求服務(wù)器
正向代理.png
正向代理,用戶對服務(wù)器不可見,服務(wù)器并不知道當前的用戶到底是誰
2.3.3 node
一些基于node的工程(例如nuxt)可以通過node進行一個代理轉(zhuǎn)發(fā),本質(zhì)也是代理
3. 瀏覽器允許的一些跨域
3.1 js文件加載
jsonp的實現(xiàn)也是基于瀏覽器允許非同源的js資源加載的前提
3.2 css文件加載
3.3 new Image 創(chuàng)建對象
可以用來實現(xiàn)埋點,但是只能發(fā)送get請求椎扬,且不能與服務(wù)器進行數(shù)據(jù)上的雙向交流,即只能 給服務(wù)器傳遞數(shù)據(jù)而不能服務(wù)器給瀏覽器返回數(shù)據(jù)