前端跨域的幾種方式(超詳細,值得收藏)

一、什麼是跨域

前端跨域的幾種方式(超詳細,值得收藏)

JavaScript出於安全方面的考慮,不允許跨域調用其他頁面的對象。那什麼是跨域呢,簡單地理解就是因為JavaScript同源策略的限制, a.com 域名下的js無法操作 b.com 或是 c.a.com 域名下的對象。

當協議、子域名、主域名、端口號中任意一個不相同時,都算作不同域。不同域之間相互請求資源,就算作“跨域”。例如:http://www.abc.com/index.html 請求 http://www.efg.com/service.php。

有一點必須要注意:跨域並不是請求發不出去,請求能發出去,服務端能收到請求並正常返回結果,只是結果被瀏覽器攔截了。之所以會跨域,是因為受到了同源策略的限制,同源策略要求源相同才能正常進行通信,即協議、域名、端口號都完全一致。

大家可以參照下圖,有助於深入理解跨域。

前端跨域的幾種方式(超詳細,值得收藏)

特別說明兩點:

第一:如果是協議和端口造成的跨域問題“前臺”是無能為力的。

第二:在跨域問題上,域僅僅是通過“URL的首部”來識別而不會根據域名對應的IP地址是否相同來判斷。“URL的首部”可以理解為“協議, 域名和端口必須匹配”。

二、什麼是同源策略及其限制

同源策略限制從一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用於隔離潛在惡意文件的關鍵的安全機制。它的存在可以保護用戶隱私信息,防止身份偽造等(讀取Cookie)。

同源策略限制內容有:

  • Cookie、LocalStorage、IndexedDB 等存儲性內容
  • DOM 節點
  • AJAX 請求不能發送

但是有三個標籤是允許跨域加載資源:

接下來我們討論下有哪些處理跨域的方法。但所有的跨域都必須經過信息提供方的允許。如果未經允許即可獲取,那是瀏覽器同源策略出現漏洞。

三、處理跨域方法一——JSONP

1.JSONP原理

利用

其中 fn 是客戶端註冊的回調的函數,目的獲取跨域服務器上的json數據後,對數據進行在處理。

最後服務器返回給客戶端數據的格式為:

fn({ msg:'this is json data'})

5.jQuery的jsonp形式

JSONP都是GET和異步請求的,不存在其他的請求方式和同步請求,且jQuery默認就會給JSONP的請求清除緩存。

$.ajax({
url: "http://crossdomain.com/jsonServerResponse",

dataType: "jsonp",
type: "get",
//可以省略
jsonpCallback: "fn",
//->自定義傳遞給服務器的函數名,而不是使用jQuery自動生成的,可省略
jsonp: "jsonp",
//->把傳遞函數名的那個形參callback變為jsonp,可省略
success: function(data) {
console.log(data);
}
});

四、處理跨域方法二——CORS

1.CORS原理

整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信

2.CORS優缺點

CORS要求瀏覽器(>IE10)和服務器的同時支持,是跨域的根本解決方法,由瀏覽器自動完成。

優點在於功能更加強大支持各種HTTP Method,缺點是兼容性不如JSONP。

只需要在服務器端做一些小小的改造即可:

header(
"Access-Control-Allow-Origin:*"
);
header(
"Access-Control-Allow-Methods:POST,GET"
);

例如:網站 http://localhost:63342/ 頁面要請求 http://localhost:3000/users/userlist 頁面,userlist頁面返回json字符串格 {name:'Mr.Cao',gender:'male',career:'IT Education'}:

//在服務器端設置同源策略地址
router.get("/userlist",function(req, res,next) {
var user = {
name: 'Mr.Cao',
gender: 'male',
career: 'IT Education'
};
res.writeHeader(200, {
"Access-Control-Allow-Origin": 'http://localhost:63342'
});
res.write(JSON.stringify(user));
res.end();
});

在響應頭上添加 Access-Control-Allow-Origin 屬性,指定同源策略的地址。同源策略默認地址是網頁的本身。只要瀏覽器檢測到響應頭帶上了CORS,並且允許的源包括了本網站,那麼就不會攔截請求響應

前端跨域的幾種方式(超詳細,值得收藏)

五、處理跨域方法三——WebSocket

Websocket是HTML5的一個持久化的協議,它實現了瀏覽器與服務器的全雙工通信,同時也是跨域的一種解決方案。WebSocket和HTTP都是應用層協議,都基於 TCP 協議。但是 WebSocket 是一種雙向通信協議,在建立連接之後,WebSocket 的 server 與 client 都能主動向對方發送或接收數據。同時,WebSocket 在建立連接時需要藉助 HTTP 協議,連接建立好了之後 client 與 server 之間的雙向通信就與 HTTP 無關了。

原生WebSocket API使用起來不太方便,我們使用Socket.io,它很好地封裝了webSocket接口,提供了更簡單、靈活的接口,也對不支持webSocket的瀏覽器提供了向下兼容。

前端跨域的幾種方式(超詳細,值得收藏)

六、處理跨域方法四——postMessage

如果兩個網頁不同源,就無法拿到對方的DOM。典型的例子是iframe窗口和 window.open方法打開的窗口,它們與父窗口無法通信。HTML5為了解決這個問題,引入了一個全新的API:跨文檔通信 API(Cross-document messaging)。這個API為window對象新增了一個 window.postMessage 方法,允許跨窗口通信,不論這兩個窗口是否同源。

postMessage方法的第一個參數是具體的信息內容,第二個參數是接收消息的窗口的源(origin),即"協議 + 域名 + 端口"。也可以設為 *,表示不限制域名,向所有窗口發送。

接下來我們看個例子: http://localhost:63342/index.html頁面向 http://localhost:3000/message.html傳遞“跨域請求信息”

前端跨域的幾種方式(超詳細,值得收藏)


分享到:


相關文章: