跨域

同源策略

瀏覽器出于安全方面的考慮,只允許與本域下的接口交互。不同源的客戶(hù)端腳本在沒(méi)有明確授權(quán)的情況下,不能讀寫(xiě)對(duì)方的資源。
本域指的是:

  • 同域名:例如都是google.com/a 和google.com/b
  • 同端口:例如都是80端口,(如果沒(méi)有寫(xiě)端口,默認(rèn)是80端口)
  • 同協(xié)議:例如都是http或者h(yuǎn)ttps

需要注意的是: 對(duì)于當(dāng)前頁(yè)面來(lái)說(shuō)頁(yè)面存放的 JS 文件的域不重要,重要的是加載該 JS 頁(yè)面所在什么域

跨域的實(shí)現(xiàn)方式

JSONP

JSONP是通過(guò)script標(biāo)簽加載數(shù)據(jù)的方式獲取數(shù)據(jù)當(dāng)做JS代碼來(lái)執(zhí)行,提前在頁(yè)面上聲明一個(gè)函數(shù),函數(shù)名通過(guò)接口傳參的方式傳給后臺(tái),后臺(tái)解析到函數(shù)名后在原始數(shù)據(jù)上 ‘ 包裹 ’ 這個(gè)函數(shù)名發(fā)送給前端。換句話(huà)說(shuō),JSONP需要對(duì)應(yīng)接口的后端的配合才能實(shí)現(xiàn)。

function fn(data){
  console.log(data);
}
<script src="http://api.jirengu.com/seather.php?callback=fn"></script>

假設(shè)后端返回?cái)?shù)據(jù)是{weather:'晴天'},在與后端協(xié)商之后讓后端放回?cái)?shù)據(jù)為fn({'weather':'晴天'});
如上代碼,當(dāng)請(qǐng)求到達(dá)后端后,后端會(huì)去解析callback這個(gè)參數(shù)獲取到字符串fn,前端script標(biāo)簽在加載數(shù)據(jù)后會(huì)把fn({'weather':'晴天'})作為js執(zhí)行,這實(shí)際上就是調(diào)用fn這個(gè)函數(shù),同時(shí)參數(shù)是{'weather':'晴天'},所以只需要在加載前在頁(yè)面提前定義好fn這個(gè)全局函數(shù),在函數(shù)內(nèi)部處理參數(shù)即可。

CORS

CORS 全稱(chēng)是跨域資源共享(Cross-Origin Resource Sharing),是一種 ajax 跨域請(qǐng)求資源的方式,支持現(xiàn)代瀏覽器,IE支持10以上。 實(shí)現(xiàn)方式很簡(jiǎn)單,當(dāng)你使用 XMLHttpRequest 發(fā)送請(qǐng)求時(shí),瀏覽器發(fā)現(xiàn)該請(qǐng)求不符合同源策略,會(huì)給該請(qǐng)求加一個(gè)請(qǐng)求頭:Origin,后臺(tái)進(jìn)行一系列處理,如果確定接受請(qǐng)求則在返回結(jié)果中加入一個(gè)響應(yīng)頭:Access-Control-Allow-Origin; 瀏覽器判斷該相應(yīng)頭中是否包含 Origin 的值,如果有則瀏覽器會(huì)處理響應(yīng),我們就可以拿到響應(yīng)數(shù)據(jù),如果不包含瀏覽器直接駁回,這時(shí)我們無(wú)法拿到響應(yīng)數(shù)據(jù)。所以 CORS 的表象是讓你覺(jué)得它與同源的 ajax 請(qǐng)求沒(méi)啥區(qū)別,代碼完全一樣。

var http = require('http');
var path = require('path');
var fs = require('fs');
var url = require('url');

http.createServer(function(req,res){
  var pathObj = url.parse(req.url,true);
});

switch (pathObj.pathname) {
  case 'getNews':
    var news = [
      'news1',
      'news2'
    ];

    //在響應(yīng)頭加上該屬性,
    //瀏覽器會(huì)去比較Oringin是否一致,一致則允許請(qǐng)求,得到該數(shù)據(jù),不一樣就拒絕
    //*星號(hào)表示任何人都可以使用該數(shù)據(jù)
    res.setHeader('Access-Control-Allow-Origin','*');
    
    res.end(JSON.stringify(news));
    break;
  default:
   fs.readFile(path.join(_dirname,pathObj.pathname), function (e,data){
     if(e){
       res.writeHead(404,'not found');
       res.end('<h1>404 Not Found</h1>');
     }else{
       res.end(data);
     }
   }).listen(8080);
}

降域

對(duì)于frame;一般情況下dom是無(wú)法獲取操作不同域下的frame數(shù)據(jù),如果有需求,可以使用降域的方式來(lái)實(shí)現(xiàn),不過(guò)降域?qū)崿F(xiàn)是有條件限制的,舉例來(lái)說(shuō),
a.google.com這個(gè)頁(yè)面中有一個(gè)iframe地址是b.google.com,那么我們可以這樣實(shí)現(xiàn)降域,如下:

<script>
  //實(shí)現(xiàn)降域
  document.domain = 'google.com';
</script>
postMessage

如果域名完全不同的情況下需要操作frame,可以使用postMessage;
window.postMessage允許多個(gè) window/frame之間跨域傳遞數(shù)據(jù)和信息,該方法可以通過(guò)綁定window的message事件來(lái)監(jiān)聽(tīng)發(fā)送跨文檔消息傳輸內(nèi)容

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么是跨域? 2.) 資源嵌入:、、、等dom標(biāo)簽,還有樣式中background:url()、@font-fac...
    電影里的夢(mèng)i閱讀 2,475評(píng)論 0 5
  • 什么是同源策略 同源政策(same-origin policy)是指同域名(或ip),同端口,同協(xié)議視為同一個(gè)域,...
    小囧兔閱讀 687評(píng)論 0 1
  • 歡迎關(guān)注微信公眾號(hào):全棧工廠(chǎng) 本文主要參考跨域資源共享 CORS 詳解[http://www.ruanyifeng...
    liqingbiubiu閱讀 2,051評(píng)論 0 3
  • 16:00我們到海生館集合,準(zhǔn)備參加今晚的夜宿活動(dòng)。這是非常適合大人小孩體驗(yàn)的,與白天隔著玻璃窗看海生動(dòng)物完全不同...
    木登閱讀 722評(píng)論 0 1
  • 常常會(huì)有朋友問(wèn):“你脫單了嗎”。相信這也是很多人經(jīng)常遇到的問(wèn)題。 與之相類(lèi)似的還有,你上高中了嗎,你讀大學(xué)了嗎,你...
    PedroPei閱讀 263評(píng)論 0 0

友情鏈接更多精彩內(nèi)容