前端面試準備--7.通信類

1.什么是同源策略及限制

1.同源策略限制從一個源加載的文檔或腳本與來自另一個源的資源進行交互继效。 ( 這是一個用于隔離潛在惡意文件的關鍵的安全機制。)
2.一個包括:協(xié)議捍岳、域名涕烧、端口
(這三個有一個不一樣就是源不一樣,就是我們所說的跨域了)
http:// 協(xié)議
www.xxx.com 域名
沒指名端口默認80
3.限制:不是一個源的文檔沒有權利去操作另一個源的文檔菜谣;

主要限制在幾個方面:

  • Cookie、LocalStorage 和 IndexDB 無法讀取
    --操作不了Cookie晚缩、LocalStorage尾膊、IndexDB
  • DOM無法獲得
    --無法獲取和操作另一個資源的DOM
  • Ajax請求不能發(fā)送(同源下的通信方式)
    --Ajax只適合同源的通信(跨域就不行了)

2.前后端如何通信

1、Ajax
--同源下的通信方式
2荞彼、WebSocket
--不受同源策略的限制
3冈敛、CORS
--支持跨域通信,也支持同源通信

3.如何創(chuàng)建Ajax

1鸣皂、XMLHttpRequest對象的工作流程
2抓谴、兼容性處理
3、事件的觸發(fā)條件
4寞缝、事件的觸發(fā)順序

    function ajax(url,fnSucc,fnFaild){
    
        //1癌压、創(chuàng)建一個對象(兼容IE6寫法)
        var xhr = XMLHttpRequest ? new XMLHttpRequest(): 
                  new ActiveXObject('Microsoft.XMLHTTP');
        
        //2、連接服務器荆陆,確定對象的發(fā)送方式:xhr.open(type,url,true);
        xhr.open('GET',url,true);
        
        //3滩届、發(fā)送請求
        xhr.send();

        //4、接受服務器返回(響應)
        xhr.onreadyStateChange = function(){
        
            if(xhr.readyState == 4){//完成
                
     //如果加載媒體資源需要再加上xhr.status===206
    (媒體資源特別大被啼,不是一次性返回過來的帜消,是資源的一部分;服務端給你下發(fā)的http狀態(tài)碼是206浓体,
     這個地方不加206泡挺,是收不到響應的)
                
                if (xhr.status === 200 || xhr.status === 304) {
                    fuSucc(xhr.responseText);
                }else{
                   if(fnFaild){
                     fnFaild(xhr.status);
                   }
                }
            }
            
        };
    }

4.跨域通信的幾種方式

1、JSONP

     1.在什么時候用:
     --在出現(xiàn)postMessage汹碱、CORS之前一直用JSONP做跨域通信的粘衬;
     2.怎么做到的:
       -- 利用script標簽的異步加載來實現(xiàn)的;
     (一個頁面是www.immoc.com咳促,script標簽地址的域名100%不是(js的地址和域名是不一致的)稚新,
       跨源了,不影響script加載)--這就是jsonp能夠實行的一個最初的基本原理跪腹;
                    
     3.怎么實現(xiàn)的:
     --需要給服務端傳遞一個回調的名褂删,這個回調的名就是我用加載script標簽的方式發(fā)出一個請求去,
    你給我返回一塊內容冲茸,這個內容是一個js塊也就是script的塊屯阀,這個塊中有回調名加代碼就能運行了缅帘,
            
--原理:(利用這個發(fā)出請求了,告訴服務端callback的名稱,將來要作為函數(shù)名來返回的难衰,既然是函數(shù)名,
要創(chuàng)建一個函數(shù)钦无,所以在調jsonp的時候 ,本地必須有一個jsonp的這么全局函數(shù)盖袭,后面才能把給的數(shù)據(jù)能
執(zhí)行出來失暂,當函數(shù)來運行。)
            
  callback后面名字叫什么都可以鳄虱; 
  <script src="http://www.abc.com/?data=name&callback=jsonp"></script>
        
-告訴它一個回調的名稱,而且要在window注冊一個全局的一個函數(shù)弟塞,然后下面的createScript就是要動
態(tài)創(chuàng)建一個script標簽,最后返回這個東西拙已。最后script.onload是監(jiān)聽腳本的加載事件决记,如果響應完了,
也會響應onload,然后判斷onload是不是成功倍踪,成功了以后看能不能拿到那個數(shù)據(jù)系宫。最后不要忘了刪除這
個函數(shù)變量window[callbackName]=null;最后往html中增加script標簽目的就是把這個請求發(fā)送出去。
        
        
3.1.1.服務器給你下發(fā)的是一個script內容建车,利用回調的東西笙瑟,執(zhí)行了后面的代碼
        <script>
            jsonp({
                data:{
                }
            });
        </script>
        
        jsonp.js:
        box({name:'xxx'});
        
        function createJs(sUrl){
            var oScript = document.createElement('script');
            oScript.type = "text/javascript";
            oScript.src = sUrl;
            document.getElementsByTagName('head')[0].appendChild(oScript);
        }
        
        createJs('jsonp.js?callback=box');
        
        function box(json){
            alert(json.name);
        }

2、Hash(url地址中#后面的東西)

        --Hash的變動頁面不會刷新
       url中?后面的叫search:search的改變是會刷新頁面的癞志;所以search不能做跨域通信;
    
      // 利用hash框产,場景是當前頁面 A 通過iframe或frame嵌入了跨域的頁面 B凄杯,跨域給B發(fā)消息
      
      // 在A中偽代碼如下:
      var B = document.getElementsByTagName('iframe');
      B.src = B.src + '#' + 'data';
      
      // 在B中的偽代碼如下
      window.onhashchange = function () {
          var data = window.location.hash;
      };
      
      **跨域給B發(fā)消息:
      先拿到B這個窗口的地址src,然后通過hash的方式后面發(fā)一段字符串秉宿,這個字符串可以是通過
      完整的json戒突,最后通過json.stringify()把json轉成字符串發(fā)給B,你是發(fā)出去了描睦,B能不能接收
      到膊存,B在自己的代碼中增加一個window.onhashchange,這個事件是用來監(jiān)聽你當前頁面的hash有
      沒有改變。之前的頁面是src忱叭,現(xiàn)在的頁面加一個hash隔崎,所以對B來說,你的url的hash變化了韵丑,
      就可以拿到了爵卒。拿到了以后通過window.location.hash就能拿到hash的具體內容。
      window.location.hash可不是拿到一個撵彻,如果hash后面等于data除了A發(fā)送過來的東西還有別的
      拼接钓株,回來要特殊處理一下实牡。

3、postMessage(html5新增加的處理跨域通信的)

        同源策略的目標就是限制跨域通信轴合,但是實際業(yè)務中又需要跨域通信创坞;
        html5中出現(xiàn)了這個標準postMessage,用這個實現(xiàn)跨域通信受葛;
        
          // 窗口A(http:A.com)向跨域的窗口B(http:B.com)發(fā)送信息
          Bwindow.postMessage('data', 'http://B.com');
          // 在窗口B中監(jiān)聽
          Awindow.addEventListener('message', function (event) {
              console.log(event.origin);
              console.log(event.source);
              console.log(event.data);
          }, false);
          
        **怎么發(fā)送:
       在A窗口题涨,給誰發(fā)送,要選中哪個窗口奔坟,調postMessage這個API携栋,第一個參數(shù)是發(fā)送的數(shù)據(jù)部分,
       這里推薦使用字符串格式咳秉;第二個是接收方那個源婉支,*是可以給任何窗口發(fā)送(很多窗口都能接收
       到你的信息,這個是不安全的)澜建,推薦的做法是加上一個源向挖;

        **發(fā)送對方怎么接受:
            B窗口要做哪些事情呢?
            就是要監(jiān)聽message事件炕舵,
            window.addEventListener('message',響應函數(shù)何之,true/false指定捕獲還是冒泡);
            要拿的就是下面這三個參數(shù):
            //來判斷發(fā)送者的源,在你的響應程序中咽筋,你要選擇性的接收溶推;比如我只接收來自A.com的
            信息,其他的一律不接收奸攻,那么就通過event.origin這個屬性來判斷
              console.log(event.origin);
              console.log(event.source);//引用A窗口的對象
              console.log(event.data);//發(fā)送的消息通過event.data拿到數(shù)據(jù)

4蒜危、WebSocket(不受同源策略限制的,拿來跨域通信正合適)

【參考資料】http://www.ruanyifeng.com/blog/2017/05/websocket.html

          1.聲明一個webSocket對象睹耐,這個地方有兩種辐赞,ws、wss區(qū)別一個加密一個非加密硝训,
           后面指向服務器的一個地址响委,這樣就建立了相當于JS一個對象來管理這個鏈接。
          var ws = new WebSocket('wss://echo.websocket.org');
    
           2.請求發(fā)送出去
          ws.onopen = function (evt) {
              console.log('Connection open ...');
              ws.send('Hello WebSockets!');
          };
    
           3.對方給消息怎么接收窖梁,通過這個參數(shù)的data來拿到
          ws.onmessage = function (evt) {
              console.log('Received Message: ', evt.data);
              ws.close();
          };
    
          4.最后這個鏈接不用了赘风,中斷了,監(jiān)聽onclose來確定是不是關閉了
          ws.onclose = function (evt) {
              console.log('Connection closed.');
          };

5纵刘、CORS(Ajax一個變種贝次,fetch實現(xiàn)CORS通信的--新出的通信標準,可以理解為支持跨域通信的Ajax)

【參考資料】http://www.ruanyifeng.com/blog/2016/04/cors.html

  Ajax是不能發(fā)送跨域通信的彰导,瀏覽器在識別你用Ajax發(fā)送了一個跨域請求的時候蛔翅,它會在你
  http頭中加一個orgin敲茄,來允許跨域通信。如果不加這個頭山析,就是一個普通的Ajax堰燎,遇到跨域通信,
  瀏覽器就會攔截了(非法的不允許請求)笋轨。
        
          
  // url(必選)秆剪,options(可選),then就是回調成功爵政,回調類似ES6的promise的寫法仅讽;
     catch就是捕獲錯誤。
          
          fetch('/some/url/', {
              method: 'get',
              }).then(function (response) {
    
                 }).catch(function (err) {
            // 出錯了钾挟,等價于 then 的第二個參數(shù)洁灵,但這樣更好用更直觀
          });
          
    *CROS為什么就能支持跨域的這種通信?   
    瀏覽器會攔截ajax請求掺出,如果它覺得這個ajax請求是跨域的徽千,它會在http請求中,加一個origin
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末汤锨,一起剝皮案震驚了整個濱河市双抽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闲礼,老刑警劉巖牍汹,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柬泽,居然都是意外死亡柑贞,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門聂抢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人棠众,你說我怎么就攤上這事琳疏。” “怎么了闸拿?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵空盼,是天一觀的道長。 經(jīng)常有香客問我新荤,道長揽趾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任苛骨,我火速辦了婚禮篱瞎,結果婚禮上苟呐,老公的妹妹穿的比我還像新娘。我一直安慰自己俐筋,他們只是感情好牵素,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澄者,像睡著了一般笆呆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上粱挡,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天赠幕,我揣著相機與錄音,去河邊找鬼询筏。 笑死榕堰,一個胖子當著我的面吹牛,可吹牛的內容都是我干的屈留。 我是一名探鬼主播局冰,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼灌危!你這毒婦竟也來了康二?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤勇蝙,失蹤者是張志新(化名)和其女友劉穎沫勿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體味混,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡产雹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翁锡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔓挖。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖馆衔,靈堂內的尸體忽然破棺而出瘟判,到底是詐尸還是另有隱情,我是刑警寧澤角溃,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布拷获,位于F島的核電站,受9級特大地震影響减细,放射性物質發(fā)生泄漏匆瓜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驮吱。 院中可真熱鬧茧妒,春花似錦、人聲如沸糠馆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽又碌。三九已至九昧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毕匀,已是汗流浹背铸鹰。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留皂岔,地道東北人蹋笼。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像躁垛,于是被迫代替她去往敵國和親剖毯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內容