瀏覽器跨域問題解決方案

一,概述

  1. 爲何會出現跨域問題
    同源策略是瀏覽器安全的基石,首先由NetScape 公司引入瀏覽器,目前全部瀏覽器都實行這個政策。同源策略是一種約定,所謂同源策略,指的是瀏覽器對不一樣源的腳本或文本的訪問進行限制,例如源A的js 不能讀取和設置引入的源的元素屬性。只有同協議 同域名 同端口 下才能訪問。由於瀏覽器的同源策略的存在,纔有了跨域問題。
  2. 同源策略的限制範圍
(1)cookie,LocalStorage,和IndexDB 沒法讀取

(2)DOM 沒法得到

(3)Ajax請求不能發送
  1. 沒有同源策略限制的兩大危險場景

    (1)沒有同源策略限制的接口請求:
    cookie通常用來處理登陸場景,目的是讓服務器知道誰發的此次請求。若是你請求接口進行登陸,服務端驗證經過後會在響應頭加入 Set-Cookie 字段,而後下次再發請求的時候,瀏覽器會自動將cookie 附加在HTTP請求的頭字段Cookie中,服務端就知道這個用戶已經登陸過了。問題也就來了,若是你登陸一個銀行網站A,而後又進入一個非法網站B,若是沒有同源策略,那麼非法網站就會獲取你登陸A 網站的Cookie,這樣一來不髮網站就能夠登陸你A網站的帳號隨心所欲。這就是傳說中的 CSRF攻擊javascript

    (2)沒有同源策略限制的DOM查詢:
    最多見的就是釣魚網站。 有一天你收到一封郵件,說你的銀行帳戶有風險,乾淨登陸www.yinghang.com 進行修改,你打開界面發現和你之前登陸的網站如出一轍,而後你輸入帳戶和密碼登錄後發現帳戶餘額正常,就離開了。但是你平時登陸銀行帳戶的網站是www.yinhang.com。這個釣魚網站作了什麼呢?html

html
<iframe></iframe>

js    
var ifram = window.frames['yinhang'];
var account = iframe.document.getElementById("你輸入帳戶的輸入框")
var pwd     = iframe.document.getElementById("你輸入帳戶的密碼框")

若是沒有同源策略限制,你的帳戶和密碼就會被非網站獲取java

二,跨域的解決方案(AJAX)

同源策略規定,AJAX請求只能發給同源的網址,不然就會報錯。除了架設服務器代理
(瀏覽器請求同源服務器,後者再請求外部服務),有三種方法能夠解決
  • JSONP
  • Websocket
  • CORS
  1. JSONP

它的思想是,網頁經過添加一個<script>元素,向服務器請求JSON數據,這種作法不受同源策略限制。服務器收到請求後,將數據放在一個指定名字的回調函數裏傳回來。
首先,網頁動態插入<script>元素,由它向跨源網址發出請求。web

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);
};

注意請求的查詢字符串有一個callback參數,用來指定回調函數的名字,這是JSONP必須的,服務器收到請求後,會將數據放在回調函數的參數位置返回。跨域

foo({
    "ip":"192.168.1.159"
})

因爲<script>元素請求的腳本,直接做爲代碼運行。這時只要瀏覽器定義了foo函數,該函數會被當即調用。瀏覽器

2.WebSocket

WebSocket 是一種通訊協議,使用 ws://(非加密) 和 wss://(加密)做爲協議前綴。該協議不實行同源策略,只要服務器支持,就能夠經過它進行通訊。安全

var ws = new WebSocket('wss://echo.websocket.org');

      ws.onopen = function (evt) {
          console.log('Connection open ...');
          ws.send('Hello WebSockets!');
      };

      ws.onmessage = function (evt) {
          console.log('Received Message: ', evt.data);
          ws.close();
      };

      ws.onclose = function (evt) {
          console.log('Connection closed.');
      };
3.CORS

CORS 是跨源資源分享(Cross-Origin Resource sharing) 的縮寫,它是W3c標準,是跨域AJAX請求的根本解決辦法。相比JSONP只能發GET請求,CORS容許任何類型的請求。
CORS須要瀏覽器和服務器同時支持。目前,全部瀏覽器都支持該功能,IE瀏覽器不能低於IE10。服務器

整個CORS通訊過程,都是瀏覽器自動完成,不須要用戶參與。對於開發者來講,CORS通訊與同源的AJAX通訊沒有差異,代碼徹底同樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感受。websocket

所以,實現CORS通訊的關鍵是服務器(服務器端但是判斷,讓那些域能夠請求)。只要服務器實現了CORS接口,
就能夠跨源通訊。cookie

相關文章
相關標籤/搜索