一文搞懂瀏覽器同源策略


摘要:同源策略就是指必須在同一個協議,域名,端口號下,而且三者必須一致的。

本文會從以下幾個方面講述同源策略:

  • 第一點 what:什么是同源策略
  • 第二點 why:為什么需要同源策略
  • 第三點 how:如何解決經典的跨域問題

什么是同源策略

什么是同源策略呢?通常一個概念出來之后,我會從生活的實際例子找到解析,你可以想象一下,假如你們家的房子,是不是不允許陌生人進入,如果可以隨便進入,那么久有可能被盜了,那么這個時候,鎖頭和鑰匙就出現了為了保證家的安全。

所以我們引出瀏覽器的同源策略,就是指必須在同一個協議,域名,端口號下,而且三者必須一致的。這個時候,我們就說是同源。

舉個例子:

https://www.angular.cn:80/guide/inputs-outputs
  • http:// 是我們所說的協議。
  • www.angular.cn 是我們所說的域名。
  • 80 表示端口號。

所以就會牽引出一個問題,不同源的數據交互問題,如果是以下兩個鏈接交互數據,可以通過同源策略的檢測:

https://www.angular.cn:80/guide/inputs-outputs
    https://www.angular.cn:80/guide/index

而如果是以下這樣的鏈接交互數據,則不能通過同源策略的檢測:

http://www.child.a.com/test/index.html ----失敗,域名不同
    https://www.a.com/test/index.html ----失敗,協議不同
    http://www.a.com:8080/test/index.html ----失敗,端口號不同

有哪些是不受同源策略限制

  • 頁面上的鏈接,比如 a 鏈接。
  • 重定向。
  • 表單提交。
  • 跨域資源的引入,比如:script, img, link, iframe。

解決跨域問題

既然有同源策略的限制,那么就會產生跨域問題,就是指不同源的腳本在數據交互的時候,會報錯,這個過程就是跨域。

那么有什么解決方案?

  • JSONP 解決跨域
  • CORS 解決跨域

總的來說,這兩個比較經典,工作中比較常用,所以先講講上面的方案。

JSONP 解決跨域

什么是 JSONP,舉個例子,就是 a.com/jsonp.html 想要獲取 b.com/main.js 的數據,這個時候由於瀏覽器同源策略,是獲取不到數據的,所以我們可以在 a.com/jsonp.html 創建一個 script 腳本,http://b.com/main.js?callback=xxx。在main.js中調用這個回調函數xxx,並且以JSON數據形式作為參數傳遞,完成回調。我們來看看代碼:

// a.com/jsonp.html中的代碼
      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://b.com/main.js?callback=foo');
      } //window.onload是為了讓頁面加載完成后再執行
      function foo(data) { 
            console.log(data.name+"歡迎您");
      };
     
    //b.com/main.js中的代碼
    foo({name:"hl"})

存在以下幾點問題:

  • 只能使用 GET 請求方式,無法使用 POST 請求方式。
  • 可能被注入惡意代碼,篡改頁面內容,可以采用字符串過濾來規避此問題。

CORS 解決跨域

CORS是一個W3C標准,全稱是"跨域資源共享"(Cross-origin resource sharing)。
它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
剛才的例子中,在b.com里面添加響應頭聲明允許a.com的訪問,代碼:

    Access-Control-Allow-Origin: http://a.com

然后a.com就可以用ajax獲取b.com里的數據了。

 

點擊關注,第一時間了解華為雲新鮮技術~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM