參考鏈接:https://mp.weixin.qq.com/s/4G_27oRLSMMYBFvtYZgqcg
一、什么是跨域
當兩個域名的協議、子域名、主域名、端口號中有任意一個不相同的時候,兩者之間的請求便存在跨域。
1、什么是同源策略及其限制內容
同源策略是一種約定,它是瀏覽器最核心也是最基本的安全功能。如果缺少了同源策略,瀏覽器很容易遭受XSS、CSRF等攻擊。所謂同源是指'協議+域名(子域名、主域名)+端口號'三者相同,即便兩個不同域名指向同一個IP,也不屬於同源。
2、常見的跨域場景
特別說明:
HTML標簽中img、link、script的這三個標簽允許跨域加載資源
注:
1.請求跨域了,那么請求有沒有發出去?
跨域並不是請求發不出,請求能正常發送並且服務器也能正常接收和返回結果,只不過結果被瀏覽器攔截了。
2.為什么表單方式可以發起跨域請求而Ajax不能?
歸根結底,跨域是為了阻止用戶讀取到另一個域名下的內容。Ajax可以獲取響應,瀏覽器認為不安全攔截了響應。但是表單並不會獲取新的內容,所以可以發起跨域請求。同時也說明了跨域並不能完全阻止CSRF,因為請求已經發出去了。
二、跨域解決方案
1、JSONP
原理:利用script標簽沒有跨域限制的漏洞,網頁可以得到其他動態來源的JSON數據。此方式需要目標服務器支持才能實現。
1.1 Ajax與JSONP對比
原則上兩者都是客戶端向服務端發送請求並獲取服務端返回的數據。但是Ajax屬於同源策略,JSONP屬於非同源策略。
1.2 JSONP的優缺點
優點:JSONP的兼容性好,能解決大部分主流瀏覽器的跨域數據訪問的問題。
缺點:JSONP僅僅支持get請求,對數據安全性無法保障
1.3 Jquery中ajax通過jsonp獲取跨域數據示例
請求方JS代碼:
$(function () { $.ajax({ url:'http://test.cache.com/index/checkjsonp.html', dataType:'jsonp', type:'get', jsonpCallback:'checkCallback', //自定義傳遞給服務器的函數名,而不是使用jQuery自動生成的,可省略 jsonp:"callback", success:function (data) { console.log(data) }, error:function () { alert('error') } }) });
跨域服務器返回PHP代碼:
public function checkJsonp() { echo "checkCallback(".json_encode(array('success'=>1)).")"; }
返回結果:
2、HTTP訪問控制(CORS)
2.1 原理:
CORS需要瀏覽器和服務器同時支持,IE8和9需要通過XDomainRequest來實現,存在一定的兼容性問題。
瀏覽器會自動的進行CORS通信,實現CORS通信的關鍵在於服務器。只要服務器實現了CORS,也就實現了跨域
2.2 實現:
服務端設置 Access-Control-Allow-Origin 就可以開啟CORS。該屬性表示那些域名可以訪問該網站,如果設置成通配符則表示所有網站均可訪問
2.3 示例:
JS代碼:
$(function () { $.ajax({ url:'http://test.cache.com/index/checkjsonp.html', dataType:'json', type:'get', success:function (data) { console.log(data) }, error:function () { alert('error') } }) });
PHP代碼:
public function checkJsonp() { header("Access-Control-Allow-Origin:http://initial.think6.com"); header('Access-Control-Allow-Methods:OPTIONS, GET, POST'); // 允許option,get,post請求 header('Access-Control-Allow-Headers:x-requested-with'); // 允許x-requested-with請求頭 echo json_encode(array('success'=>1)); }
返回結果:
3、WebSocket
原理:WebSocket是一種通信協議,它實現了瀏覽器與服務器之間的全雙工通信(即通信雙方可以同時發動和接收信息的信息交互方式)。同時websocket並不實行同源策略,只要服務器支持,它就可以實現跨域通信。
4、Node中間件代理
原理:同源策略是瀏覽器需要遵循的標准,服務器向服務器請求則無需遵循同源策略,從而實現跨區數據請求。
5、nginx反向代理
實現原理類似於Node中間件,需要搭建一個中轉nginx服務器,用於轉發請求。使用nginx反向代理實現跨域是最簡單的方式,只需要修改nginx服務器配置即可解決跨域問題,支持所有瀏覽器、session。無需修改代碼且不會影響服務器性能。