摘要:關于跨域為什么會有跨域我們得先了解下同源策略。簡而言之,同協議同域名同端口號什么是跨域跨域就是采取技術方案突破同源策略的限制,實現不同域之間交互請求響應。
關于跨域 why?
為什么會有跨域?
我們得先了解下 ==同源策略(SOP, Same Origin Policy)==。
瀏覽器出于安全方面的考慮,只能訪問與包含它的頁面位于同一個域中的資源,該策略為通信設置了“相同的協議、相同的域、相同的端口”這一限制。試圖訪問上述限制之外的資源,都會引發安全錯誤。這種安全策略可以預防某些惡意行為。
簡而言之,
同協議 Same Protocol
同域名 Same Hostname
同端口號 Same Port
Same Protocol && Same Hostname && Same Port
What?什么是跨域?
==跨域就是采取技術方案突破同源策略的限制,實現不同域之間交互(請求響應)。==
How?那么如何實現跨域呢?
有以下幾種方法。
==方法一==
CORS (Cross-Origin Resource Sharing,跨域源資源共享),是一種ajax跨域請求資源的方式,支持現代瀏覽器,IE支持10以上,通過XMLHttpRequest實現Ajax通信的一個主要限制就是同源策略。
CORS是W3C的一個工作草案,定義了在必須訪問跨境資源時,瀏覽器和服務器該如何溝通。CORS的基本思想,就時使用自定義的HTTP頭部讓瀏覽器和服務器進行溝通,從而決定請求或者響應應該成功還是失敗。
實現思路:使用XMLHttpRequest發送請求時,瀏覽器會給該請求自動添加一個請求頭:Origin。服務器經過一系列處理,如果確定請求來源頁面屬于白名單,則在響應頭部加入首部字段:Access-Control-Allow-Origin。瀏覽器比較請求頭部的Origin 和響應頭部的 Access-Control-Allow-Origin是否一致,一致的話,瀏覽器得到響應數據。如果服務器沒有設置Access-Control-Allow-Origin 或者這個頭部源信息不匹配,瀏覽器就會駁回請求。
模擬CORS的實現
步驟1.
如何偽裝一個網站(在本地)?
1.編輯hosts文件
蘋果mac: 直接在git bash上輸入命令行操作即可 “sudo vi /etc.hosts” ,或者下載一些圖形界面應用軟件直接修改。
Windows操作系統:
win鍵(四個方塊的鍵)+ R = 彈開運行窗口
復制該文件路徑 c:windowssystem32driversetc
選中hosts文件,右鍵-屬性-安全-選擇組或用戶名(添加修改保存的權限的對象)- 編輯 - 再次選擇組或用戶名(添加修改保存的權限的對象 - 勾選權限(選項在此不表)
打開hosts文件,寫入 127.0.0.1 localhost;127.0.0.1 bai.com;127.0.0.1 google.com;可以寫入你任何你想模擬的網站,按照這種對應關系格式即可, ip地址+域名。
步驟2.
所需工具
node.js && git bash(模擬服務器),一個簡單的html頁面里面有個跨域請求的Ajax通信。
hello world
//nodeJS模擬后端響應CORS的實現 var http = require("http"); var fs = require("fs"); var url = require("url"); var path = require("path"); http.createServer(function(req, res){ var urlObj = url.parse(req.url, true) switch (urlObj.pathname){ case "/getNews": var news = ["NBA Break News","CBA Break News"] //CORS的實現 res.setHeader("Access-Control-Allow-Origin","http://google.com:8080") /*res.setHeader("Access-Control-Allow-Origin","*") 服務器設置公用接口 */ res.end(JSON.stringify(news)); break; case "/" : if(urlObj.pathname == "/") { urlObj.pathname += "index.html" } default: var filePath = path.join(__dirname, urlObj.pathname); fs.readFile(filePath,"binary", function(error, fileContent){ if(error){ console.log("404") res.writeHeader(404, "not found") res.end("404,not found
") }else { res.write(fileContent, "binary") } }) } }).listen(8080);
上面代碼就是CORS實現的過程。
在本地修改hosts文件,127.0.0.1 google.com, 頁面的url為 http://google.com:8080。
在title為google的頁面上添加一個ajax請求,該請求以get方法會向baiduServer的端口("http://baidu.com:8080/getNews")發送一個請求。
瀏覽器會給請求頭加上Origin: http://google.com:8080, Request URL: http://baidu.com:8080/getNews。
baiduServer后端,響應頭添加首部字段。Access-Control-Allow-Origin: http://google.com:8080。 表明該服務器(baiduServer)接受請求并給予響應。
瀏覽器比較請求頭部的Origin 和響應頭部的 Access-Control-Allow-Origin是否一致,一致的話,瀏覽器得到響應數據。如果服務器沒有設置Access-Control-Allow-Origin: http://google.com:8080 或者這個頭部源信息不匹配,瀏覽器就會駁回請求。
當然服務器也可以設置公用接口, res.setHeader("Access-Control-Allow-Origin","*")
服務器設置公用接口, 任何人都可以使用該服務器這個端口的數據。
==方法二==
JSONP,是JSON with padding的簡寫(填充式JSON或參數式JSON)。
JSONP的原理,通過動態 -->