跨域,顧名思義,即爲請求了不一樣域的資源。
瞭解跨域這件事,咱們先看看致使會存在跨域問題的根源:瀏覽器的同源策略
瀏覽器的同源策略又是什麼鬼? 好像瞭解一點,可是又說不清楚。此次咱們就來詳細探索一下。javascript
聲明一下,本文是參考衆多其餘有關跨域文章結合本身技術認識所作的記錄,請與
瀏覽器同源政策及其規避方法參考着看更加合適。html
MDN
維基百科:
In computing, the same-origin policy is an important concept in the web application security model. Under the policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, host name, and port number. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page's Document Object Model.
簡單翻譯一下:
在web應用安全模型中,同源策略是一個重要的概念。在該策略下,僅倆個頁面有相同的源, web瀏覽器才容許包含在第一個頁面中的腳本訪問第二個web頁面的數據。源被定義爲 URI協議,主機名,端口號的組合。該策略阻止了一個頁面的惡意腳本經過文檔對象模型(DOM)得到其餘的web頁面的敏感數據.
那爲何會有同源策略呢,能夠參考一下,CSRF這篇文章談到CSRF這種狀況。
那哪些數據會被限制呢?
敏感數據通常指的是瀏覽器中的Cookies, SessionStorage, LocalStorage, IndexedDB數據, CacheStorage, ApplicationCache...;java
阮一峯老師還對同源策略對於非同源,限制的行爲作了概括:web
「 若是非同源,共有三種行爲受到限制。 (1) Cookie、LocalStorage 和 IndexDB 沒法讀取。 (2) DOM 沒法得到。 (3) AJAX 請求不能發送。 雖然這些限制是必要的,可是有時很不方便,合理的用途也受到影響。下面,我將詳細介紹,如何規避上面三種限制。 」
瀏覽器容許經過設置document.domain共享 Cookie。
document.domain的寫操做是有要求的。只能寫入基礎域名和當前域名,其餘域名是沒法寫入的,因此domain這種方式只能在親子域名之間共享cookies
// 因爲尚未相關資源(三級域名資源,域名資源),沒有作驗證跨域
頁面1 localhost:8080的頁面,包含一個頁面2 (iframe = http://localhost:8081); 頁面2中訪問window.parent.document報跨源錯誤 在頁面2中window.parent能夠訪問,可是在iframe中訪問獲取到的window.parent對象中屬性缺乏了有關DOM的部分,而直接在頁面1中查看window對象,能夠看到document屬性對象,而使用誇源window.parent沒法獲取document屬性對象
因此這種方式,不管是否誇源,父窗口能夠經過更改子窗口的iframe的src中的hash值來傳遞數據給子窗口;
可是 在存在跨源的狀況下,子窗口獲取parent.location.href(可寫不可讀)讀操做會報跨源錯誤,因此子窗口課件寫入url的方式傳遞數據給父窗口。
片斷識別符方式能夠父傳子,子傳父。瀏覽器
document.getElementById('iframe').contentWindow.name
訪問出錯,因此沒法跨域安全
頁面1 調用iframe的iframe.contentWindow.postMessage(data,"http://localhost:8081")
頁面2 調用window的 window.parent.postMessage(data,'http://localhost:8080')服務器
「 同源政策規定,AJAX請求只能發給同源的網址,不然就報錯。 除了架設服務器代理(瀏覽器請求同源服務器,再由後者請求外部服務),有三種方法規避這個限制。 JSONP WebSocket CORS 」
// 客戶端(瀏覽器頁面) function addScriptTag(src) { var script = document.createElement('script'); script.setAttribute("type","text/javascript"); script.src = src; document.body.appendChild(script); } window.onload = function () { addScriptTag('http://example.com/ip?callback=foo');//須要指定回調函數名 } function foo(data) { console.log('Your public IP address is: ' + data.ip); }; //服務端 foo({ "ip": "8.8.8.8" });
CORS是跨源資源分享(Cross-Origin Resource Sharing)的縮寫。它是W3C標準,是跨源AJAX請求的根本解決方法。相比JSONP只能發GET請求,CORS容許任何類型的請求。
請參考 阮老師的跨域資源共享 CORS 詳解cookie