跨域的幾種實現(xiàn)方式

概念1:同源策略

同源策略串结,Same-origin policy蒿柳,瀏覽器處于安全考慮阵难,只允許與本域下的接口交互岳枷。不同源的客戶端腳本在沒有明確授權(quán)的情況下,不能讀寫對方的資源呜叫。

概念2:本域

  • 相同的協(xié)議
  • 相同的域名
  • 相同的端口

跨域

因為瀏覽器的同源策略空繁,如果不加特殊處理,在一個頁面中向不同域的接口發(fā)送請求是不會得到數(shù)據(jù)的朱庆,這種向不同域的接口發(fā)送請求的行為就是跨域盛泡。

實現(xiàn)跨域

方式

  • JSONP
  • CORS
  • 降域
  • postMessage

JSONP

原理:

html中的script標(biāo)簽可以引入其他域下的js,利用這個特性可以達(dá)到跨域娱颊。

通過script.src指定域名發(fā)送請求
后端經(jīng)過處理返回特定的字符串(函數(shù)格式)
返回的數(shù)據(jù)作為參數(shù)傳入一個數(shù)據(jù)處理函數(shù)
這時執(zhí)行JS中的數(shù)據(jù)處理函數(shù)就可以實現(xiàn)數(shù)據(jù)交換傲诵,達(dá)到跨域的目的凯砍。

代碼演示:
<!DOCTYPE html>
<html>
<head>
  <meta chartset="utf-8">
  <title>跨域-jsonp</title>
</head>
<body>
  <button>點我</button>
  <ul class="news"></ul>
 
  <script>
    var btn = document.querySelector("button")

    btn.addEvevtListener('click',function(){
      var script = document.createElement('script')
      script.src = 'http://localhost:8080/getNews?callback=appendHtml'
      document.head.appendChild(script)
      document.head.removeChild(script)
    })

    function appendHtml(news){
      var html = ''
      html += '<li>' + news + '</li>'
      var addnews = document.querySelector('.news')
      addnews.innerHTML = html
    }
  </script>
</body>
</html>
-----------------------------------------------
使用mock-server模擬后端

router.get('/getnews',function(req,res){
  var news = ["test1","test2","test3","test4","test5"]
  var data = []

  var index = parseInt(math.random()*news.length)
  data.push(news[index])

  var cb = req.query.callback
  if(cb){
    res.send(cb + '(' + JSON.stringify(data) + ')')  //在后端將返回的數(shù)據(jù)處理成函數(shù)格式返回到JS后執(zhí)行,達(dá)到跨域目的
  }else{ res.send(data)}
  
})
效果
JSONP結(jié)果.png

CORS

Cross-Origin Resource Sharing拴竹,跨域資源共享悟衩,是一種ajax跨域請求資源的方法。

原理

當(dāng)使用XMLHttpRequest發(fā)送請求時栓拜,當(dāng)瀏覽器發(fā)現(xiàn)請求不符合同源策略時座泳,瀏覽器會給該請求加一個請求頭origin,值為當(dāng)前頁面的域名,通過后端處理幕与,返回結(jié)果中加入一個響應(yīng)頭Access-Control-Allow-Origin挑势,如果值也為origin或者"*",則可以拿到數(shù)據(jù)啦鸣,實現(xiàn)跨域薛耻。

代碼演示
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>跨域-cors</title>
</head>
<body>
  <button class="btn">點我</button>
  <ul class="news"></ul>

  <script>
    var btn = document.querySelector('.btn')

    btn.addEventListener("click",function(){
      var xhr = new XMLHttpRequest()
      xhr.open('get','http://b.jirengu.com:8080/getNews',true)
      xhr.send()
      xhr.onreadystatechange = function(){
        if(xhr.readyState === 4 && xhr.status === 200){
          appendHtml(JSON.parse(xhr.responseText))
        }
      }
      window.xhr = xhr
    })

    function appendHtml(news){
      var addnews = ducument.querySelector('.news')
      var html = ''

      html += '<li>' + news + '</li>'
      addnews.innerHTML= html
    }
  </script>
</body>
</html>

-------------------------------------------------------------------------

使用mock-server模擬后端

router.get('/getNews',function(req,res){
  var news = ['test1','test2','test3','test4','test5','test6','test7']
  var data = []
  var index = parseInt(Math.random()*news.length)

  data.push(news[index])

  res.header("Access-Control-Allow-Origin","http://a.jrg.com:8080")
  // res.header("Access-Control-Allow-Origin","*")
  res.send(data)
})
效果
修改host.PNG
CORS結(jié)果.PNG

降域

對于頁面中使用iframe嵌套另外的網(wǎng)站時,如果符合同源策略赏陵,就可以通過window.frames[].document操作對應(yīng)iframe里的網(wǎng)站,如果不符合饲漾,則不能相互訪問蝙搔,但是如果這些網(wǎng)站有著相同的主網(wǎng)站,則可以通過降域?qū)崿F(xiàn)跨域考传。例如:a.test.com:8080和b.test.com:8080的主域名為test.com:8080

原理

在script標(biāo)簽里寫上document.domain = "主域名"吃型,就可以實現(xiàn)降域,
然后就可以使用window.frames[].document操作對應(yīng)iframe里的網(wǎng)站僚楞,實現(xiàn)跨域勤晚。

代碼演示
創(chuàng)建a.html文件

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>跨域-降域-a</title>
</head>
<body>
  <div class="ct">
    <div class="main">
      <input type="text" placeholder="http://a.jirengu.com:8080/a.html">
    </div>
    <iframe src="http://b.jirengu.com:8080/b.html"></iframe>
  </div>
  <script>
    document.querySelector('.main input').addEventListener('input',function(){
      windows.frames[0].document.querySelector('input').value = this.value
    })
    document.domain = "jirengu.com"
  </script>
</body>
</html>

----------------------------------------------------------------

創(chuàng)建b.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>b.html</title>
</head>
<body>
  <input type="text" placeholder="http://b.jirengu.com:8080/b.html">

  <script>
    document.querySelector('input').addEventListener('input',function(){
      windows.parent.document.querySelector('input').value = this.value
    })
    document.domain = "jirengu.com"
  </script>
</body>
</html>
效果

在前面已修改了hosts文件,將測試用的a.jirengu.com和b.jirengu.com寫入到hosts中對應(yīng)127.0.0.1泉褐,然后使用server-mock模擬后端赐写。

降域1.PNG
降域2.PNG

postMessage

postMessage()方法允許來自不同源的腳本采用異步方式進(jìn)行有限的通信,可以實現(xiàn)跨文本檔膜赃、多窗口挺邀、跨域消息傳遞。

postMessage(data,origin)方法接受兩個參數(shù)

data:要傳遞的數(shù)據(jù)
origin:可以設(shè)置目標(biāo)窗口的url跳座,只包括協(xié)議端铛、域名、端口疲眷。也可以設(shè)置為"*",表示傳遞給任意窗口

原理

postMessage可向任意窗口發(fā)送數(shù)據(jù)禾蚕,由目標(biāo)窗口選擇接受數(shù)據(jù)。

通過postMessage()發(fā)送數(shù)據(jù)狂丝,然后再寫一個監(jiān)聽函數(shù)就可以實現(xiàn)跨域操作换淆。

代碼演示
創(chuàng)建a.html文件

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>跨域-降域-a</title>
</head>
<body>
  <div class="ct">
    <div class="main">
      <input type="text" placeholder="http://a.jirengu.com:8080/a.html">
    </div>
    <iframe src="http://b.jirengu.com:8080/b.html"></iframe>
  </div>
  <script>
    var input = document.querySelector('.main input')

    input.addEventListener('input',function(){
      window.frames[0].postMessage(this.value,"*")
    })

    window.addEventListener('message',function(e){
      input.value = e.data
    })
    
  </script>
</body>
</html>

----------------------------------------------------------------

創(chuàng)建b.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>b.html</title>
</head>
<body>
  <input type="text" placeholder="http://b.jirengu.com:8080/b.html">

  <script>
    var input = document.querySelector('input')

    input.addEventListener('input',function(){
      window.parent.postMessage(this.value,'http://a.jirengu.com:8080')
    })

    window.addEventListener('message',function(e){
      input.value = e.data
    })
    
  </script>
</body>
</html>
效果

這個demo演示效果和降域一樣哗总。

以上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末产舞,一起剝皮案震驚了整個濱河市魂奥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌易猫,老刑警劉巖耻煤,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異准颓,居然都是意外死亡哈蝇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進(jìn)店門攘已,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炮赦,“玉大人,你說我怎么就攤上這事样勃》涂保” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵峡眶,是天一觀的道長剧防。 經(jīng)常有香客問我,道長辫樱,這世上最難降的妖魔是什么峭拘? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮狮暑,結(jié)果婚禮上鸡挠,老公的妹妹穿的比我還像新娘。我一直安慰自己搬男,他們只是感情好拣展,可當(dāng)我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著止后,像睡著了一般瞎惫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上译株,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天瓜喇,我揣著相機與錄音,去河邊找鬼歉糜。 笑死乘寒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的匪补。 我是一名探鬼主播伞辛,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼烂翰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蚤氏?” 一聲冷哼從身側(cè)響起甘耿,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竿滨,沒想到半個月后佳恬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡于游,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年毁葱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贰剥。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡倾剿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚌成,到底是詐尸還是另有隱情前痘,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布担忧,位于F島的核電站际度,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涵妥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一坡锡、第九天 我趴在偏房一處隱蔽的房頂上張望蓬网。 院中可真熱鬧,春花似錦鹉勒、人聲如沸帆锋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锯厢。三九已至,卻和暖如春脯倒,著一層夾襖步出監(jiān)牢的瞬間实辑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工藻丢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剪撬,地道東北人。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓悠反,卻偏偏與公主長得像残黑,于是被迫代替她去往敵國和親馍佑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容

  • JSONP CORS 降域 對于頁面中使用iframe嵌套另外的網(wǎng)站時梨水,如果符合同源策略拭荤,就可以通過window....
    Gia_Mo閱讀 214評論 0 0
  • JSONP JSONP 是JSON with padding(填充式JSON 或參數(shù)式JSON)的簡寫;JSONP...
    Schrodinger的貓閱讀 327評論 0 0
  • 跨域以及跨域的幾種方式 講解跨域之前我們先來看看什么是同源策略 什么是同源策略 通常來說疫诽,瀏覽器出于安全方面的考慮...
    尾巴尾巴尾巴閱讀 1,609評論 0 1
  • 什么是同源策略舅世? 同源策略是指,瀏覽器出于安全方面的考慮踊沸,只允許與本域下的接口交互歇终。不同源的客戶端腳本在沒有明確授...
    upup_dayday閱讀 257評論 0 0
  • 什么是跨域 瀏覽器出于安全方面的考慮,只允許客戶端與本域(同協(xié)議逼龟、同域名评凝、同端口,三者缺一不可)下的接口交互腺律。不同...
    七里之境閱讀 1,355評論 0 0