跨域問題

內(nèi)容主要來源于:ajax跨域完全講解
本文主要講解跨域的產(chǎn)生問題及解決思路盆佣,并不直接給出某個(gè)具體問題的解決方案

1. 跨域的產(chǎn)生

跨域是瀏覽器的限制
凡是發(fā)送請(qǐng)求url的協(xié)議,域名坝疼,端口三者之間任意一個(gè)與當(dāng)前頁面地址不同即是跨域

  • 同源策略:
    指的是瀏覽器對(duì)不同源的腳本或者文本的訪問方式進(jìn)行的限制。比如源a的js不能讀取或設(shè)置引入的源b的元素屬性谆沃。那么先定義下什么是同源裙士,所謂同源,就是指兩個(gè)頁面具有相同的協(xié)議管毙,主機(jī)(也常說域名),端口桌硫,三個(gè)要素缺一不可夭咬。


  • 受同源策略限制的內(nèi)容
    js中的XMLHttpRequest等請(qǐng)求

  • 不受同源策略限制的內(nèi)容
    頁面中的鏈接:跨域資源嵌入,如<script src="..."></script>铆隘,<img>卓舵,<link>,<iframe>等膀钠,但瀏覽器限制了js不能讀寫加載的內(nèi)容掏湾,

2. html解決跨域

iframe:

這個(gè)功能主要包括接受信息的"message"事件和發(fā)送消息的"postMessage"方法。比如baidu.com域的A頁面通過iframe嵌入了一個(gè)google.com域的B頁面肿嘲,可以通過以下方法實(shí)現(xiàn)A和B的通信

  1. A頁面通過postMessage方法發(fā)送消息:
window.onload = function() {  
    var ifr = document.getElementById('ifr');  
    var targetOrigin = "http://www.google.com";  
    ifr.contentWindow.postMessage('hello world!', targetOrigin);  
};  
  1. B頁面通過message事件監(jiān)聽并接受消息:
var onmessage = function (event) {  
  var data = event.data;//消息  
  var origin = event.origin;//消息來源地址  
  var source = event.source;//源Window對(duì)象  
  if(origin=="http://www.baidu.com"){  
  console.log(data);//hello world!  
  }  
};  
if (typeof window.addEventListener != 'undefined') {  
  window.addEventListener('message', onmessage, false);  
} else if (typeof window.attachEvent != 'undefined') {  
  //for ie  
  window.attachEvent('onmessage', onmessage);  
} 


3. 跨域解決思路

3.1 瀏覽器禁止檢查

在控制臺(tái)輸入下面內(nèi)容融击,即可允許跨域

chrome --disable-web-security --user-data-dir=g:\temp3

缺點(diǎn):瀏覽器禁止檢查是客戶端的行為,但是不可能在每個(gè)人的電腦上都通過這個(gè)方法去解決

3.2 jsonp(json pending)

jsonp是動(dòng)態(tài)創(chuàng)建script標(biāo)簽雳窟,使用完后就立即銷毀尊浪,所以無法通過查看dom元素頁面代碼的形式查看jsonp是否生成script腳本。
使用jsonp時(shí),后臺(tái)需要返回javascript腳本(后臺(tái)需要改動(dòng))拇涤,它是一個(gè)函數(shù)捣作,參數(shù)是使用的返回值。
實(shí)際項(xiàng)目中JSONP通常用來獲取json格式數(shù)據(jù)鹅士,這時(shí)前后端通常約定一個(gè)參數(shù)callback券躁,該參數(shù)的值,就是處理返回?cái)?shù)據(jù)的函數(shù)名稱掉盅。

// 前端請(qǐng)求
    $.ajax({
      method: 'get',
      url: config + '/admin/login/getLoginState',
      dataType: 'jsonp',
      success: (res) => {
        if (res.username) {
          this.setState({
            userName: res.username,
            isLogin: true
          });
        }
      }
    });

// 后臺(tái)代碼
  async getLoginStateAction() {
    var role = await this.session('role');
    var username = await this.session('username');
    var result = {
      role: role,
      username: username
    };
    this.jsonp(result);
  }

缺點(diǎn):

  • 服務(wù)器需要改動(dòng)代碼支持
  • 只支持get
  • 發(fā)出的不是xhr請(qǐng)求

3.3 跨域:

解決跨域的思路

3.3.1 被調(diào)用方? 支持代理

基于http在支持跨域上的一些規(guī)定也拜,在響應(yīng)頭上添加指定字段,告訴瀏覽器怔接,它允許被調(diào)用方調(diào)用搪泳。

實(shí)現(xiàn)方法:

  • 服務(wù)器端實(shí)現(xiàn)
    向服務(wù)器端添加以下請(qǐng)求頭
Access-Control-Allow-Origin: *  // 允許所有的域名訪問,可以根據(jù)請(qǐng)求的頭來變化
Access-Control-Allow-Methods: *    // 允許所有的方法訪問扼脐,可以根據(jù)請(qǐng)求的頭來變化

?? 跨域請(qǐng)求是先執(zhí)行請(qǐng)求岸军,還是先判斷是跨域的請(qǐng)求?
請(qǐng)求有簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求之分瓦侮,如果是簡(jiǎn)單請(qǐng)求艰赞,瀏覽器會(huì)先請(qǐng)求后判斷是否跨域,如果是非簡(jiǎn)單請(qǐng)求肚吏,瀏覽器會(huì)發(fā)送域解命令通過之后在請(qǐng)求方妖。

?? 注:

  • 簡(jiǎn)單請(qǐng)求:
    GET、HEAD罚攀、POST
    請(qǐng)求頭中党觅,無自定義頭
    Content-Type為以下幾種:text/plain、multipart/form-data斋泄、application/x-www-form-urlaencoded
  • 非簡(jiǎn)單請(qǐng)求:
    PUT杯瞻、delete方法的Ajax請(qǐng)求
    發(fā)送json格式的Ajax請(qǐng)求
    帶自定義頭的Ajax請(qǐng)求

?? Access-Control-Allow-Origin: * // 允許所有的域名訪問,可以根據(jù)請(qǐng)求的頭來變化是否滿足所有請(qǐng)求呢炫掐?
使用帶cookie的請(qǐng)求時(shí)魁莉,會(huì)出現(xiàn)以下問題:


這是因?yàn)樵谑褂脦ookie的請(qǐng)求時(shí),必須將Access-Control-Allow-Origin設(shè)置為對(duì)應(yīng)的域名募胃,而不是允許所有的域名

將指定為對(duì)應(yīng)的域名后旗唁,會(huì)出現(xiàn):


Access-Control-Allow-Credentials設(shè)置為true,讓服務(wù)器允許cookie即可

但是這樣請(qǐng)求會(huì)讓服務(wù)端局限與一個(gè)域名調(diào)用
解決思路
將客戶端的請(qǐng)求origin獲取到痹束,把它設(shè)置為Access-Control-Allow-Origin就可以允許所有的域名調(diào)用
將客戶端的請(qǐng)求header獲取到检疫,把它設(shè)置為Access-Control-Allow-Headers就可以允許所有的自定義請(qǐng)求頭

  • nginx配置


  • apache配置


3.3.2 調(diào)用方? 隱藏代理

跨域請(qǐng)求不是從瀏覽器直接發(fā)送到被調(diào)用方,而是從中間的服務(wù)器轉(zhuǎn)發(fā)的
反向代理:
nginx配置


apache配置


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末参袱,一起剝皮案震驚了整個(gè)濱河市电谣,隨后出現(xiàn)的幾起案子秽梅,更是在濱河造成了極大的恐慌,老刑警劉巖剿牺,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件企垦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡晒来,警方通過查閱死者的電腦和手機(jī)钞诡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來湃崩,“玉大人荧降,你說我怎么就攤上這事≡芏粒” “怎么了朵诫?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長薄扁。 經(jīng)常有香客問我剪返,道長,這世上最難降的妖魔是什么邓梅? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任脱盲,我火速辦了婚禮,結(jié)果婚禮上日缨,老公的妹妹穿的比我還像新娘钱反。我一直安慰自己,他們只是感情好匣距,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布面哥。 她就那樣靜靜地躺著,像睡著了一般毅待。 火紅的嫁衣襯著肌膚如雪幢竹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天恩静,我揣著相機(jī)與錄音,去河邊找鬼蹲坷。 笑死驶乾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的循签。 我是一名探鬼主播级乐,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼县匠!你這毒婦竟也來了风科?” 一聲冷哼從身側(cè)響起撒轮,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贼穆,沒想到半個(gè)月后题山,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡故痊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年顶瞳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愕秫。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡慨菱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出戴甩,到底是詐尸還是另有隱情符喝,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布甜孤,位于F島的核電站协饲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏课蔬。R本人自食惡果不足惜囱稽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望二跋。 院中可真熱鬧战惊,春花似錦、人聲如沸扎即。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谚鄙。三九已至各拷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闷营,已是汗流浹背烤黍。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留傻盟,地道東北人速蕊。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像娘赴,于是被迫代替她去往敵國和親规哲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • 視頻參考:ajax跨域完全講解 本文精華版:【綜合】ajax跨域問題 什么是跨域問題 簡(jiǎn)單來講诽表,當(dāng)前臺(tái)調(diào)用后臺(tái)唉锌,如...
    一顆語法糖閱讀 1,078評(píng)論 2 8
  • 1. 什么是跨域隅肥? 跨域一詞從字面意思看,就是跨域名嘛袄简,但實(shí)際上跨域的范圍絕對(duì)不止那么狹隘腥放。具體概念如下:只要協(xié)議...
    他在發(fā)呆閱讀 822評(píng)論 0 0
  • 跨域問題的場(chǎng)景和解決方案多種多樣,只要是做前端開發(fā)痘番,總會(huì)遇到捉片。而且面試時(shí)也是必問的問題。所以自己學(xué)習(xí)總結(jié)記錄一下汞舱。...
    花開_陳鳳娟閱讀 737評(píng)論 0 0
  • 1. 什么是跨域? 跨域一詞從字面意思看伍纫,就是跨域名嘛,但實(shí)際上跨域的范圍絕對(duì)不止那么狹隘昂芜。具體概念如下:只要協(xié)議...
    稍縱即逝_(tái)e5e9閱讀 196評(píng)論 0 0
  • 瀏覽器在請(qǐng)求不同域的資源時(shí)泌神,會(huì)因?yàn)橥床呗缘挠绊懻?qǐng)求不成功良漱,這就是通常被提到的“跨域問題”。作為前端開發(fā)欢际,解決跨域...
    SCQ000閱讀 2,554評(píng)論 1 52