什麼是同源策略?
同源策略阻止從一個域上加載的腳本獲取或操作另一個域上的文檔屬性。也就是說,受到請求的 URL 的域必須與當前 Web 頁面的域相同。這意味着瀏覽器隔離來自不同源的內容,以防止它們之間的操作。這個瀏覽器策略很舊,從 Netscape Navigator 2.0 版本開始就存在。
URL 說明 是否允許通信
http://www.a.com/a.js
http://www.a.com/b.js 同一域名下 允許
http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同一域名下不同文件夾 允許
http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允許
http://www.a.com/a.js
https://www.a.com/b.js 同一域名,不同協議 不允許
http://www.a.com/a.js
http://70.32.92.74/b.js 域名和域名對應ip 不允許
http://www.a.com/a.js
http://script.a.com/b.js 主域相同,子域不同 不允許
http://www.a.com/a.js
http://a.com/b.js 同一域名,不同二級域名(同上) 不允許(cookie這種情況下也不允許訪問)
http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允許
常用的跨域解決方案
jsonp(JSON withPadding): 簡單點說,異步請求跨域的服務器端時,不是直接返回數據,而是返回一個js方法,把數據作爲參數傳過來。這需要服務器端稍作修改,如果只是跨域傳遞數據(而不是DOM操作),個人認爲這種方式是最好的。參考內容:使用 JSONP 實現跨域通信
服務器端代理:由js請求同源的服務器端,再由服務器端做代理來實現跨域的請求。參考內容:ajax 跨域之服務端代理
動態創建script:雖然瀏覽器默認禁止了跨域訪問,但並不禁止在頁面中引用其他域的JS文件,並可以自由執行引入的JS文件中的function,根據這一點,可以方便地通過創建script節點的方法來實現完全跨域的通信有點XSS跨站腳本***的意思,所以安全性方面需要仔細評估。這也是所有GreaseMonkey的實現方式,比如sogou的雲輸入法。
document.domain:僅適用於不同的二級域名之間的跨域訪問。
window.name:name 在瀏覽器環境中是一個全局/window對象的屬性,且當在 frame 中加載新頁面時,name 的屬性值依舊保持不變。通過在 iframe 中加載一個資源,該目標頁面將設置 frame 的 name 屬性。此 name 屬性值可被獲取到,以訪問 Web 服務發送的信息。參考使用 window.name 解決跨域問題
window.location.hash:hash可以實現跨域傳值從而達到跨域通訊的目標。爲了及時捕獲 Hash值的修改,需要輪詢實現。如果是iframe和主頁面不在同一個域下而要進行通訊,這是不錯的方式。不過會導致一個問題,在chrome和 firefox這類瀏覽器中,hash值的修改會在瀏覽器中保存記錄,擾亂正常的前進和後退功能。
iframe 代理:iframe和主頁面不在同一個域,但iframe 需要操作主頁面的DOM結構,這個時候用iframe代理可實現,比如iframe高度自適應,只要在iframe中再插入一個與主頁面同域的 iframe,把參數傳遞過去即可。