一、同源政策 跨域問題其實就是瀏覽器的同源策略造成的。同源策略限制了從同一個源載入的文檔或腳本如何與另一個源的資源進行交互。這是瀏覽器的一個用於隔離潛在惡意文件的重要的安全機制。同源指的是:協議、埠號、功能變數名稱必須一致。同源策略:protocol(協議)、domain(功能變數名稱)、port(埠)三者必須 ...
一、同源政策
- 跨域問題其實就是瀏覽器的同源策略造成的。同源策略限制了從同一個源載入的文檔或腳本如何與另一個源的資源進行交互。這是瀏覽器的一個用於隔離潛在惡意文件的重要的安全機制。同源指的是:協議、埠號、功能變數名稱必須一致。同源策略:protocol(協議)、domain(功能變數名稱)、port(埠)三者必須一致。同源政策的目的主要是為了保證用戶的信息安全,它只是對 js 腳本的一種限制,並不是對瀏覽器的限制,對於一般的 img、或者script 腳本請求都不會有跨域的限制,這是因為這些操作都不會通過響應結果來進行可能出現安全問題的操作。同源政策主要限制了三個方面。
- 當前域下的 js 腳本不能夠訪問其他域下的 cookie、LocalStorage、SessionStorage 和 indexDB。
- 當前域下的 js 腳本不能夠操作訪問操作其他域下的 DOM。
- 當前域下 ajax 無法發送跨域請求。
二、解決跨域問題方法
1.CORS
- 跨域資源共用(CORS) 是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器 讓運行在一個 origin (domain)上的Web應用被准許訪問來自不同源伺服器上的指定的資源。當一個資源從與該資源本身所在的伺服器不同的域、協議或埠請求一個資源時,資源會發起一個跨域HTTP 請求。CORS需要瀏覽器和伺服器同時支持,整個CORS過程都是瀏覽器完成的,無需用戶參與。因此實現CORS的關鍵就是伺服器,只要伺服器實現了CORS請求,就可以跨源通信了。
2.JSONP
- jsonp的原理就是利用script標簽沒有跨域限制,通過script標簽src屬性,發送帶有callback參數的GET請求,服務端將介面返回數據拼湊到callback函數中,返回給瀏覽器,瀏覽器解析執行,從而前端拿到callback函數返回的數據。
- 缺點:具有局限性, 僅支持get方法;不安全,可能會遭受XSS攻擊。
3.postMessage跨域
- 解決問題:
- 頁面和其打開的新視窗的數據傳遞
- 多視窗之間消息傳遞
- 頁面與嵌套的iframe消息傳遞
- 上面三個場景的跨域數據傳遞
- 用法:
- postMessage(data,origin)方法接受兩個參數
- data: html5規範支持任意基本類型或可複製的對象,但部分瀏覽器只支持字元串,所以傳參時最好用JSON.stringify()序列化。
- origin: 協議+主機+埠號,也可以設置為"*",表示可以傳遞給任意視窗,如果要指定和當前視窗同源的話設置為"/"。
4.nginx代理跨域
-
Nginx 是一款輕量級的 Web 伺服器,也可以用於反向代理、負載平衡和 HTTP 緩存等。Nginx 使用非同步事件驅動的方法來處理請求,是一款面向性能設計的 HTTP 伺服器。傳統的 Web 伺服器如 Apache 是 process-based 模型的,而 Nginx 是基於event-driven模型的。正是這個主要的區別帶給了 Nginx 在性能上的優勢。Nginx 架構的最頂層是一個 master process,這個 master process 用於產生其他的 worker process,這一點和Apache 非常像,但是 Nginx 的 worker process 可以同時處理大量的HTTP請求,而每個 Apache process 只能處理一個。
-
nginx代理跨域,實質和CORS跨域原理一樣,通過配置文件設置請求響應頭Access-Control-Allow-Origin…等欄位。
-
跨域問題:同源策略僅是針對瀏覽器的安全策略。伺服器端調用HTTP介面只是使用HTTP協議,不需要同源策略,也就不存在跨域問題。
5.nodejs中間件代理跨域
- node中間件實現跨域代理,原理大致與nginx相同,都是通過啟一個代理伺服器,實現數據的轉發,也可以通過設置cookieDomainRewrite參數修改響應頭中cookie中功能變數名稱,實現當前域的cookie寫入,方便介面登錄認證。
6.document.domain + iframe跨域
- 此方案僅限主域相同,子域不同的跨域應用場景。實現原理:兩個頁面都通過js強制設置document.domain為基礎主域,就實現了同域。
7.location.hash + iframe跨域
- 實現原理:a欲與b跨域相互通信,通過中間頁c來實現。 三個頁面,不同域之間利用iframe的location.hash傳值,相同域之間直接js訪問來通信。
8.window.name + iframe跨域
9.WebSocket協議跨域
- WebSocket protocol是HTML5一種新的協議。它實現了瀏覽器與伺服器全雙工通信,同時允許跨域通訊,是server push技術的一種很好的實現。
三、正向代理與反向代理的區別
-
正向代理和反向代理的結構是一樣的,都是 client-proxy-server 的結構,它們主要的區別就在於中間這個 proxy 是哪一方設置的。在正向代理中,proxy 是 client 設置的,用來隱藏 client;而在反向代理中,proxy 是 server 設置的,用來隱藏 server。
-
正向代理:
-
客戶端想獲得一個伺服器的數據,但是因為種種原因無法直接獲取。於是客戶端設置了一個代理伺服器,並且指定目標伺服器,之後代理伺服器向目標伺服器轉交請求並將獲得的內容發送給客戶端。這樣本質上起到了對真實伺服器隱藏真實客戶端的目的。實現正向代理需要修改客戶端,比如修改瀏覽器配置。
-
-
反向代理:
-
伺服器為了能夠將工作負載分不到多個伺服器來提高網站性能 (負載均衡)等目的,當其受到請求後,會首先根據轉發規則來確定請求應該被轉發到哪個伺服器上,然後將請求轉發到對應的真實伺服器上。這樣本質上起到了對客戶端隱藏真實伺服器的作用。一般使用反向代理後,需要通過修改 DNS 讓功能變數名稱解析到代理伺服器 IP,這時瀏覽器無法察覺到真正伺服器的存在,當然也就不需要修改配置了。
-