跨域
瀏覽器發(fā)送的請求地址(URL)與所在頁面的地址 不同(端口/協(xié)議/域名 其一不同)挖帘。簡言之麻裳,瀏覽器發(fā)出的請求url铭腕,與其所在頁面的url,不一樣邮旷。此時,同源機制會讓瀏覽器拒收 服務器響應回來的數(shù)據(jù)笛求。
同源機制
同源策略/SOP(Same origin policy)是一種約定廊移,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能探入,如果缺少了同源策略狡孔,瀏覽器很容易受到XSS、CSFR等攻擊蜂嗽。所謂同源是指"協(xié)議+域名+端口"三者相同苗膝,即便兩個不同的域名指向同一個ip地址,也非同源植旧。不同源的客戶端腳本在沒有明確授權的情況下辱揭,不能讀寫對方的資源。
三種解決方式
JSONP
JSONP(JSON with padding(添加))是通過 script 標簽加載數(shù)據(jù)的方式病附,去獲取數(shù)據(jù)问窃,并把數(shù)據(jù) 當做 JS 代碼來執(zhí)行:提前在頁面上聲明一個函數(shù),函數(shù)名通過接口傳參的方式傳給后臺完沪,后臺解析到函數(shù)名后在原始數(shù)據(jù)上「包裹」這個函數(shù)名域庇,發(fā)送給前端。換句話說覆积,JSONP 需要對應接口的后端的配合才能實現(xiàn)听皿。
jsonp缺點:只能實現(xiàn)get一種請求。JSONP太駭客宽档,不如下面的CORS正統(tǒng)尉姨。
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 傳參一個回調函數(shù)名給后端,方便后端返回時執(zhí)行這個在前端定義的回調函數(shù)
script.src = 'http://www.domain2.com:8080/login?callback=handleCallback';
document.head.appendChild(script);
// 回調執(zhí)行函數(shù)
function handleCallback(res) {
alert(JSON.stringify(res));
}
</script>
// 服務端返回如下(返回時即執(zhí)行全局函數(shù))
handleCallback({"status": true, "user": "admin"})
這個請求到達后端后吗冤,后端會去解析callback這個參數(shù)又厉,獲取到字符串handleCallback九府,在發(fā)送數(shù)據(jù)時調用handleCallback這個函數(shù),把數(shù)據(jù)作為參數(shù)傳過來馋没。 用戶只需要在加載 提前在頁面定義好handleCallback這個全局函數(shù)昔逗,在函數(shù)內部處理參數(shù)即可。
CORS
CORS 全稱是 跨域資源共享(Cross-Origin Resource Sharing)篷朵,是一種 ajax 跨域請求資源的方式勾怒,支持現(xiàn)代瀏覽器,IE支持10以上声旺。 實現(xiàn)方式很簡單笔链,
1 當你使用 XMLHttpRequest 發(fā)送請求時,瀏覽器發(fā)現(xiàn)該請求不符合同源策略腮猖,會給該請求加一個請求頭:Origin鉴扫;(瀏覽器無需做設置 只需發(fā)送ajax)
2 后臺服務器收到請求后,會進行一系列處理澈缺,如果確定接受請求坪创,則在返回結果中加入一個響應頭:Access-Control-Allow-Origin (換言之,服務器允許的域url姐赡,會加入此響應頭莱预,相當于一個憑證);
3 瀏覽器判斷該相應頭中是否包含 Origin 的值,如果有项滑,則瀏覽器會處理響應依沮,我們就可以拿到響應數(shù)據(jù),如果不包含枪狂,瀏覽器直接駁回危喉,這時我們無法拿到響應數(shù)據(jù)。
所以 CORS 的表象是讓你覺得它與同源的 ajax 請求沒啥區(qū)別州疾,代碼完全一樣辜限。
postMessage
通過讓iframe的js元素,執(zhí)行postmessage()严蓖,以發(fā)送消息給iframe訪問的url網(wǎng)站列粪,如果網(wǎng)站服務器收到消息(即 監(jiān)聽到了 以該消息為名 的事件)并進行處理,則瀏覽器可以實現(xiàn)一定程度的跨域谈飒。
瀏覽器發(fā)送數(shù)據(jù) window.frames[0].postMessage(this.value,'*');
服務器監(jiān)聽跨域請求&瀏覽器監(jiān)聽返回的數(shù)據(jù) window.addEventListener('message',function(e) {})
參考https://blog.csdn.net/tang_yi_/article/details/79401280