什么是同源策略沐绒?
同源是指"協(xié)議+域名+端口"三者相同俩莽。
什么是跨域?
當協(xié)議出刷、子域名、主域名坯辩、端口號中任意一個不相同時馁龟,都算作不同域。不同域之間相互請求資源漆魔,就算作“跨域”坷檩。
同源策略限制內容有:
Cookie、LocalStorage改抡、IndexedDB 等存儲性內容
DOM 和 Js對象無法獲得
AJAX 請求發(fā)送后矢炼,結果被瀏覽器攔截了但是有三個標簽是允許跨域加載資源:
<img src=XXX>
<link href=XXX>
<script src=XXX>在跨域問題上,僅僅是通過“URL的首部”來識別而不會根據域名對應的IP地址是否相同來判斷阿纤【涔啵“URL的首部”可以理解為“協(xié)議, 域名和端口必須匹配。
請求跨域了欠拾,那么請求到底發(fā)出去沒有胰锌?
跨域并不是請求發(fā)不出去,請求能發(fā)出去清蚀,服務端能收到請求并正常返回結果匕荸,只是結果被瀏覽器攔截了。你可能會疑問明明通過表單的方式可以發(fā)起跨域請求枷邪,為什么 Ajax 就不會?因為歸根結底榛搔,跨域是為了阻止用戶讀取到另一個域名下的內容,Ajax 可以獲取響應东揣,瀏覽器認為這不安全践惑,所以攔截了響應。但是表單并不會獲取新的內容嘶卧,所以可以發(fā)起跨域請求尔觉。同時也說明了跨域并不能完全阻止 CSRF,因為請求畢竟是發(fā)出去了芥吟。
跨域的解決方案?
1.jsonp
JSONP原理:
利用 <script> 標簽沒有跨域限制的漏洞侦铜,網頁可以得到從其他來源動態(tài)產生的 JSON 數據专甩。JSONP請求一定需要對方的服務器做支持才可以。JSONP和AJAX對比
JSONP和AJAX相同钉稍,都是客戶端向服務器端發(fā)送請求涤躲,從服務器端獲取數據的方式。但AJAX屬于同源策略贡未,JSONP屬于非同源策略(跨域請求)JSONP優(yōu)缺點
JSONP優(yōu)點是簡單兼容性好种樱,可用于解決主流瀏覽器的跨域數據訪問的問題。
缺點是僅支持get方法具有局限性,不安全可能會遭受XSS攻擊俊卤。JSONP的實現流程:
Web前端事先定義一個用于獲取跨域響應數據的回調函數嫩挤,并通過沒有同源策略限制的script標簽發(fā)起一個請求(將回調函數的名稱放到這個請求的query參數里),然后服務端返回這個回調函數的執(zhí)行消恍,并將需要響應的數據放到回調函數的參數里岂昭,前端的script標簽請求到這個執(zhí)行的回調函數后會立馬執(zhí)行,于是就拿到了執(zhí)行的響應數據哺哼。2.cors
CORS 需要瀏覽器和后端同時支持佩抹,但實現 CORS 通信的關鍵還是后端。
服務端設置 Access-Control-Allow-Origin 就可以開啟 CORS取董。 該屬性表示哪些域名可以訪問資源棍苹,如果設置通配符則表示所有網站都可以訪問資源。
雖然設置 CORS 和前端沒什么關系茵汰,但是通過這種方式解決跨域問題的話枢里,會在發(fā)送請求時出現兩種情況,分別為簡單請求和復雜請求蹂午。
(1)簡單請求 :
GET:
發(fā)送一個請求來取得服務器上的某一資源栏豺。
HEAD:
只請求頁面的首部。
POST:
向URL指定的資源提交數據或附加新的數據豆胸。
且Content-Type
的值僅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded
(2)復雜請求:不是簡單請求的都屬于復雜請求奥洼。
PUT:
跟POST
方法很像,也是想服務器提交數據晚胡。但是灵奖,它們之間有不同。PUT
指定了資源在服務器上的位置估盘,而POST
沒有瓷患。
DELETE:
刪除服務器上的某資源。
OPTIONS:
它用于獲取當前URL所支持的方法遣妥。如果請求成功擅编,會有一個Allow的頭包含類似“GET,POST”這樣的信息。
TRACE:
該方法被用于激發(fā)一個遠程的,應用層的請求消息回路爱态。
CONNECT:
把請求連接轉換到透明的TCP/IP通道谭贪。
- 3.postMessage
postMessage是可以跨域操作的window屬性。
用于解決以下方面的問題:
多窗口之間消息傳遞肢藐;
頁面與嵌套的iframe消息傳遞故河;
postMessage()方法允許來自不同源的腳本采用異步方式進行有限的通信吱韭,可以實現跨文本檔吆豹、多窗口、跨域消息傳遞理盆。
document.getElementById('frame').contentWindow.postMessage(傳遞的信息, 目標路徑url, 可選對象);
- 4.websocket
Websocket是HTML5的一個持久化的協(xié)議痘煤,它實現了瀏覽器與服務器的全雙工通信,同時也是跨域的一種解決方案猿规。WebSocket和HTTP都是應用層協(xié)議衷快,都基于 TCP 協(xié)議。但是 WebSocket 是一種雙向通信協(xié)議姨俩,在建立連接之后蘸拔,WebSocket 的 server 與 client 都能主動向對方發(fā)送或接收數據。同時环葵,WebSocket 在建立連接時需要借助 HTTP 協(xié)議调窍,連接建立好了之后 client 與 server 之間的雙向通信就與 HTTP 無關了。
- Node中間件代理(兩次跨域)
實現原理:同源策略是瀏覽器需要遵循的標準张遭,而如果是服務器向服務器請求就無需遵循同源策略邓萨。 代理服務器,需要做以下幾個步驟:
接受客戶端請求
將請求 轉發(fā)給服務器
拿到服務器 響應 數據
-
將 響應 轉發(fā)給客戶端
6.nginx反向代理
實現原理類似于Node中間件代理菊卷,需要你搭建一個中轉nginx服務器缔恳,用于轉發(fā)請求。
使用nginx反向代理實現跨域洁闰,是最簡單的跨域方式歉甚。只需要修改nginx的配置即可解決跨域問題,支持所有瀏覽器扑眉,支持session纸泄,不需要修改任何代碼,并且不會影響服務器性能襟雷。
實現思路:通過nginx配置一個代理服務器(域名與domain1相同刃滓,端口不同)做跳板機,反向代理訪問domain2接口耸弄,并且可以順便修改cookie中domain信息咧虎,方便當前域cookie寫入,實現跨域登錄计呈。