一、什么是跨域
當a.qq.com域名下的頁?或腳本試圖去請求b.qq.com域名下的資源時,就是典型的跨域行為,跨域的定義從受限范圍可以分為兩種,?義跨域和狹義跨域,
(一)廣義跨域
?義跨域通常包含以下三種?為:
1. 資源跳轉:a鏈接、重定向,
2. 資源嵌?:<link>、<script>、<img>、<frame>等dom標簽,還有樣式中background:url()、@font-face()等?件外鏈,
3. 腳本請求:瀏覽器存盤資料讀取、dom和js物件的跨域操作、js發起的ajax請求等,
其中,資源跳轉和資源嵌??為可以正常請求到跨域資源,腳本請求在未經任何處理的情況下,通常會有跨域
(二)狹義跨域
狹義跨域正是瀏覽器同源策略限制的?類請求場景,即我們通常說的跨域?為,通常包含以下三種?為:
1. cookie、localStorage和indexDB?法讀取,
2. dom和js物件?法獲取和操作,
3. ajax請求?法發送
二、常見的跨域場景
??瀏覽器安全的基石就是“同源策略”,即如果A網站設定的cookie,B網站如果想訪問必須滿足三個要求:同一種協議、同一個域名、同一個埠號,
??舉例來說,http://www.example.com/dir/page.html這個網址,協議是http://,域名是www.example.com,埠號是80(可以省略,http默認80,https默認443)
??例如:
http://www.example.com/dir2/other.html :同源
http://example.com/dir/other.html :不同源(域名不同)??
http://v2.www.example.com/dir/other.html :不同源(域名不同
http://www.example.com:81/dir/other.html :不同源(埠不同)
三、跨域解決方法
(一)ajax跨域請求解決方案
1.jsonp跨域解決
jsonp (JSON with Padding),是JSON的?種“使?模式”,可以讓?頁跨域讀取資料,其本質是利?script標簽的開放策略,瀏覽器傳遞callback引數到后端,后端回傳資料時會將callback引數作為函式名來包裹資料,從?瀏覽器就可以跨域請求資料并定制函式來?動處理回傳資料,
代碼示例:
var script = document.createElement('script'); script.type = 'text/javascript'; // 傳參callback給后端,后端回傳時執?這個在前端定義的回呼函式 script.src = https://www.cnblogs.com/wangguoxinyue/archive/2022/05/09/'http://a.qq.com/index.php?callback=handleCallback'; document.head.appendChild(script); // 回呼執?函式 function handleCallback(res) { alert(JSON.stringify(res)); }
- jsonp跨域優點:
jsonp兼容性強,適?于所有瀏覽器,尤其是IE10及以下瀏覽器,
- jsonp跨域缺點:
沒有關于調?錯誤的處理,
只?持GET請求,不?持POST請求以及?資料量的請求,?且也?法拿到相關的回傳頭,狀態碼等資料,
callback引數惡意注?,可能會造成xss漏洞,
2.跨域資源共享(CORS)
跨域資源共享(Cross-origin resource sharing,CORS)是?個 W3C標準,允許瀏覽器向跨域服務器發送請求,從?克服了ajax只能同源使?的限制,CORS需要瀏覽器和服務器同時?持,?前,所有主流瀏覽器(IE10及以上)使?XMLHttpRequest物件都可?持該功能,IE8和IE9需要使?XDomainRequest物件進?兼容,
CORS整個通信程序都是瀏覽器?動完成,瀏覽器?旦發現ajax請求跨源,就會?動在頭資訊中增加Origin欄位,?來說明本次請求來?哪個源(協議+域名+端?),因此,實作CORS通信的關鍵是服務器,需要服務器配置Access-Control-Allow-Origin頭資訊,當CORS請求需要攜帶cookie時,需要服務端配置Access-Control-Allow-Credentials頭資訊,前端也需要設定withCredentials,瀏覽器將CORS請求分成兩類:簡單請求和?簡單請求,簡單請求需要滿?以下兩?條件:
1. 請求?法是以下三種?法之?:HEAD、GET、POST,
2. HTTP的頭資訊不超出以下?種欄位:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type:只限
于三個值application/x-www-form-urlencoded、multipart/form-data、text/plain,
CORS簡單請求跨域實作流程:

// IE8/9需?XDomainRequest兼容 var xhr = new XMLHttpRequest(); // 前端設定是否帶cookie xhr.withCredentials = true; xhr.open('post', 'http://a.qq.com/index.php', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('user=saramliu'); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } };
- CORS跨域優點:
?持所有型別的HTTP請求,功能完善,
通過onerror事件監聽進?調?錯誤處理;
通過Access-Control-Allow-Origin進?資源訪問授權,
- CORS跨域缺點:
?前主流瀏覽器(IE10及以上)都?持CORS,但IE8和IE9需要使?XDomainRequest物件進?兼容,IE7及以下瀏覽器不?持
3.服務器代理
服務器代理,顧名思義即在發送跨域請求時,后端進?代理中轉請求?服務器端,然后將獲取的資料回傳給前端,?般適?于以下場景:
針對IE7及以下瀏覽器摒棄Flash插件的情況,配置代理接?與前端頁?同源,并中轉?標服務器接?,則ajax請求不存在跨域問題,外?前端頁??法訪問內?接?,配置代理接?允許前端頁?訪問,并中轉內?接?,則外?前端頁?可以跨域訪問內?接?,
服務器代理實作流程:
- 服務器代理優點:
在不使?Flash的情況下,兼容不?持CORS的瀏覽器跨域請求,
- 服務器代理缺點:
后端需要?定的改造?作量,
(?)前端跨域通信解決?案
前端跨域通信是指瀏覽器中兩個不符合同源策略的前端頁?進?通信,
1.document.domain+iframe
document.domain+iframe?案代碼?例:
<!-- A頁? http://a.qq.com/a.html --> <iframe id="iframe" src="http://b.qq.com/b.html"></iframe> <script> document.domain = "qq.com"; var windowB = document.getElementById("iframe").contentWindow; alert("B頁?的user變數:" + windowB.user); </script>
<!-- B頁? http://b.qq.com/b.html --> <script> document.domain = "qq.com"; var user = "saramliu"; </script>
- document.domain+iframe?案優點:
實作邏輯簡單,?需額外中轉頁?
- document.domain+iframe?案缺點:
僅適?于主域相同,?域不同的前端通信跨域場景
2.location.hash+iframe
當兩個不符合同源策略且主域不同的頁?需要進?跨域通信時,可以利?url的hash值改變但不重繪頁?的特性,實作簡單的前端跨域通信,
<!-- A頁? http://a.qq.com/a.html --> <iframe id="iframe" src="http://b.qq1.com/b.html"></iframe> <script> // 監聽c.html傳來的hash值 window.onhashchange = function () { alert("B頁?傳遞資料:" + location.hash.substring(1)); }; </script> <!-- B頁? http://b.qq1.com/b.html --> <iframe id="iframe" src="http://a.qq.com/c.html"></iframe> <script> // 向c.html傳遞hash值 var iframe = document.getElementById('iframe'); setTimeout(function() { iframe.src = iframe.src + '#user=saramliu'; }, 1000); </script> <!-- C頁? http://a.qq.com/c.html --> <script> // 監聽b.html傳來的hash值 window.onhashchange = function () { // 操作同域a.html的hash值,傳遞資料 window.parent.parent.location.hash = window.location.hash.substring(1); }; </script>
- location.hash+iframe?案優點
可以解決主域不同的前端通信跨域問題,
hash改變,頁?不會重繪,
- location.hash+iframe?案缺點:
受部分瀏覽器安全機制限制,需要額外的同源中轉頁?,且中轉頁?需要js邏輯來修改hash值,
通信資料型別及長度均受限,且資料外顯在url上,存在?定安全風險,
3.window.name+iframe
window.name屬性的獨特之處在于,name值在不同頁?(甚?不同域名)加載后依舊存在,并且可以?持?常長的name值(2MB),
window.name+iframe代碼?例:
<!-- A頁? http://a.qq.com/a.html --> <iframe id="iframe" src="http://b.qq1.com/b.html"></iframe> <script> var state = 0; var iframe = document.getElementById('iframe'); iframe.onload = function() { if (state === 1) { // 第2次onload成功后,讀取同域window.name中資料 alert(iframe.contentWindow.name); } else if (state === 0) { // 第1次onload成功后 state = 1; } }; </script>
<!-- B頁? http://b.qq1.com/b.html --> <script> window.name = "這?是B頁?!"; window.location = "http://a.qq.com/c.html"; </script>
- window.name+iframe?案優點:
可以解決主域不同的前端通信跨域問題,
通信資料型別不受限,且長度可達2MB,
- window.name+iframe?案缺點:
需要額外的同源中轉頁?,但中轉頁可以為空?頁,
4.postMessage
postMessage是HTML5 XMLHttpRequest Level2中的API,且是為數不多可以跨域操作的window屬性之?,它通常?于解決以下??的問題:
1. 頁?和其打開的新窗?的資料傳遞,
2. 多窗?之間訊息傳遞,
3. 頁?與嵌套iframe訊息傳遞,
postMessage是?種安全的跨域通信?法,當a.html獲得對b.html的window物件后,a.html調?postMessage?法分發?個MessageEvent訊息,b.html通過監聽message事件即可獲取a.html傳遞的資料,從?實作跨域通信,
- postMessage?法的語法如下:
otherWindow.postMessage(message、targetOrigin、[transfer])
otherWindow:?標窗?的window物件,?如iframe的contentWindow屬性、執?window.open回傳的window物件等,
message:將要發送給其他window的資料,
targetOrigin:指定哪些窗?能接收到訊息事件,其值可以是字串*(表??限制)或者是“協議+主機+端?號”,
transfer(可選):是?串和message同時傳遞的Transferable物件,這些物件的所有權將被轉移給訊息的接收?,?發送??將不再保有所有權,
postMessage?案代碼?例:
<!-- A頁? http://a.qq.com/a.html --> <iframe id="iframe" src="http://b.qq1.com/b.html"></iframe> <script> var iframe = document.getElementById('iframe'); iframe.onload = function() { var data = {meesage: "這?是A頁?發的訊息"}; var url = "http://b.qq1.com/b.html"; // 向B頁?發送訊息 iframe.contentWindow.postMessage(JSON.stringify(data), url); }; window.addEventListener("message", function(e) { alert("B頁?發來訊息:" + JSON.parse(e.data)); }); </script>
<!-- B頁? http://b.qq1.com/b.html --> <script> window.addEventListener("message", function(e) { alert("A頁?發來訊息:" + JSON.parse(e.data)); var data = {meesage: "這?是B頁?發的訊息"}; var url = "http://a.qq.com/a.html"; window.parent.postMessage(JSON.stringify(data), url); }, false); </script>
- postMessage?案優點:
可以解決多種型別的前端跨域通信問題;
- postMessage?案缺點:
兼容性??相對差?點,IE8及以下瀏覽器不?持該?法,IE9只?持postMessage傳遞string型別的資料,?標準的postMessage消
息資料可以是任何型別,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/472299.html
標籤:其他
上一篇:組件設計要求
