HTML5解決跨域問題

由於瀏覽器的同源策略,網絡連接的跨域訪問是不被允許的,XHR對象不能直接與非同源的網站處理數據交互。而同源指的是什麼呢?同源的範疇包括:規則(協議),主機號(域名、ip),端口號。

但是隨着開放,共享平臺的流行,跨域訪問的需求愈加強烈。目前最常用的跨域方案是動態加入script標籤,這多少有點hack的意味,跨域訪問似乎一直沒有什麼安全且光明正大的辦法。

 

終於,HTML5提供的XMLHttpRequest Level2實現了跨域訪問以及其他的一些新功能。下面我們會詳細討論一下:

 

XMLHttpRequest  Level2

XHR2HTML5新特性中的一個(事實上沒有什麼XHR1XHR2這樣的概念,XHR2只是HTML5提供的一套新的規範),在原有XHR對象上新增了一些功能:跨域訪問,全新的事件,還有請求進度以及響應進度。

目前瀏覽器對於XHR2的兼容列表:

  • u Chrome              2.0以上
  • u Firefox              3.5以上
  • u Internet Explorer      不支持
  • u Opera               不支持
  • u Safari               4.0以上

 

原理:

正常情況下,我們書寫一個XHR示例:

var xhr = new XMLHttpRequest();

xhr.open('GET', 'http://baidu.com', true); //訪問baidu.com

xhr.send(null);

 

 

我們本地使用Chrome運行這段代碼,打開控制檯查看錯誤信息:


圖1

 

在這裏可以看到,本次請求已經被Kill掉。這是因爲,我們的頁面在本地,域是http://127.0.0.1,與請求的http://baidu.com非同源。

那麼本次請求是何時被Kill的呢,是在發出前被瀏覽器確認爲跨域請求而被立即終止了嗎?事實上,瀏覽器不僅發出了請求,還接收到了響應。然後根據響應頭的規則來確定這個域是否同源可以接收,如果不可以,瀏覽器就會報錯,接收到的數據也不會提供給腳本。

 

我們回到XHR2,上面提到,XHR對象新增了一些功能,這裏就包括跨域訪問。實現如下:

//在服務器端返回內容的頁面,設置Header Access-Control-Allow-Origin如下

Response.AddHeader("Access-Control-Allow-Origin","*") ;

 

 

這裏,我們先不討論設置的含義,先讓代碼跑起來,查看結果如何。

頁面http://inno.hotpotpro.com/FirePot/meetingdate?date=20120723已經完成如上配置,修改JS代碼如下:

 

var xhr = new XMLHttpRequest();

xhr.open('GET', 'http://inno.hotpotpro.com/FirePot/meetingdate?date=20120723', true); //訪問baidu.com

xhr.send();

 

 

刷新頁面,查看控制檯,沒有報錯。打開控制檯的“Network”選型卡:


可以看到紅線標識的部分:Access-Control-Allow-Origin:*,即爲我們在服務器端所做的設置。切換到“Response”選項卡


這是怎麼做到的呢?

瀏覽器在接收到服務器返回信息時,會檢查響應頭的Access-Control-Allow-Origin,它的值標識請求內容所允許的域。

我們之前要求服務器設置Access-Control-Allow-Origin*,表明該返回信息允許所有源訪問。如果設置爲具體的域,如http://niweisuo.com,就表明除了同源外,只允許域來自niweisuo.com的訪問。

 

注:

在使用AJAX類庫時,可能經過如上的設置,依然無法通過瀏覽器的安全限制。那麼,可以檢查一下AJAX類庫的代碼,看是否存在影響跨域設置的代碼:


如上是tangram-ajax-1.5.2.js中,影響跨域的代碼,註釋調即可,其他類庫請自調。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章