前端面試題之 Ajax

  1. 談談你對 ajax 的認識?

    • Ajax 的全稱是 Asynchronous JavaScript and XML 中文名稱定義為異步的 JavaScript 和 XML。Ajax 是 Web2.0 技術的核心由多種技術集合而成,使用 Ajax 技術不必刷新整個頁面,只需對頁面的局部進行更新,可以節(jié)省網(wǎng)絡帶寬,提高頁面的加載速度,從而縮短用戶等待時間,改善用戶體驗

    • 直白地說,就是沒用 AJAX 的網(wǎng)頁,你點一個按鈕就要刷新一下頁面,盡管新頁面上只有一行字和當前頁面不一樣,但你還是要無聊地等待頁面刷新。用了 AJAX 之后,你點擊,然后頁面上的一行字就變化了,頁面本身不用刷

    • 作用:

      • 通過 Ajax 可以使用 Javascript 語句來調(diào)用 XMLHttpRequest 對象,直接與服務器進行通訊,可以在不重載頁面的情況下與服務器交換數(shù)據(jù)
    • Ajax 的步驟:

      1. 創(chuàng)建 XMLHttpRequest 對象
        •   var xhr =  new XMLHttpRequest()
          
        • 對于IE早期版本(IE7及以下版本)使用,new ActiveXObject(\"Microsoft.XMLHTTP\")、new ActiveXObject(\"Msxml2.XMLHTTP\") 等方式創(chuàng)建對象
      2. XMLHttpRequest 對象常用屬性和常用方法
        • 屬性
          • readystate
            • 返回 XMLHTTP 請求的當前狀態(tài)碼
          • state
            • 返回當前請求的 HTTP 狀態(tài)碼
          • statusText
            • 返回 HTTP 狀態(tài)碼對應的文本
        • 方法
          • onreadystatechange
            • 監(jiān)聽 readystate 和 state 狀態(tài)
    • HTTP 請求方法

      • ajax方法:通過 HTTP 請求加載遠程數(shù)據(jù)
      • get方法: 通過遠程 HTTP GET 請求載入信息
      • post方法:通過遠程 HTTP POST 請求載入信息
      1. XMLHttpRequest 對象常用屬性和常用方法
        • 屬性
          • readystate
            • 返回 XMLHTTP 請求的當前狀態(tài)碼
          • state
            • 返回當前請求的 HTTP 狀態(tài)碼
          • statusText
            • 返回 HTTP 狀態(tài)碼對應的文本
        • 方法
          • onreadystatechange
            • 監(jiān)聽 readystate 和 state 狀態(tài)
    • HTTP 請求方法

      • ajax方法:通過 HTTP 請求加載遠程數(shù)據(jù)
      • get方法: 通過遠程 HTTP GET 請求載入信息
      • post方法:通過遠程 HTTP POST 請求載入信息
  2. ajax 請求有哪幾個步驟?

    • 共有五個步驟:
      1. 創(chuàng)建異步對象
        •   var xhr = new XMLHttpRequest();
          
      2. 設置 請求行 open(請求方式,請求url):
        •   // get請求如果有參數(shù)就需要在url后面拼接參數(shù)
            // post如果有參數(shù),就在請求體中傳遞 
            xhr.open("get","validate.php?username="+name)
            xhr.open("post","validate.php");
          
      3. 設置請求(GET方式忽略此步驟)頭:setRequestHeader()
        •   // 1.get不需要設置
            // 2.post需要設置請求頭:Content-Type:application/x-www-form-urlencoded
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
          
      4. 設置請求體 send()
        •   // 1.get的參數(shù)在url拼接了,所以不需要在這個函數(shù)中設置
            // 2.post的參數(shù)在這個函數(shù)中設置(如果有參數(shù))
            xhr.send(null) xhr.send("username="+name);
          
      5. 讓異步對象接收服務器的響應數(shù)據(jù)
        •   // 一個成功的響應有兩個條件:1.服務器成功響應了 2.異步對象的響應狀態(tài)為4(數(shù)據(jù)解析完畢可以使用了)
            xhr.onreadystatechange = function(){ 
                if(xhr.status == 200 && xhr.readyState == 4){ 
                    console.log(xhr.responseText);
            }
          
    • ajax-get方式請求案例:
      •   var xhr = new XMLHttpRequest();
          xhr.open("get","validate.php?username="+name);
          xhr.send(null);
          xhr.onreadystatechange = function(){
              if(xhr.status == 200 && xhr.readyState == 4){ 
                  console.log(xhr.responseText); 
                  document.querySelector(".showmsg").innerHTML = xhr.responseText;
              }
          }
        
    • ajax-post方式請求案例:
      •   var xhr = new XMLHttpRequest();
          xhr.open("post","validate.php");
          xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
          xhr.send("username="+name);
          xhr.onreadystatechange = function(){
              // 判斷服務器是否響應,判斷異步對象的響應狀態(tài)
              if(xhr.status == 200 && xhr.readyState == 4){
                  document.querySelector(".showmsg").innerHTML = xhr.responseText;
              }
          }
        
        
  3. 談一談對 同源策略 的理解?

    • 同源策略
      • 指的是:協(xié)議,域名,端口相同
      • 同源策略是一種安全協(xié)議,指一段腳本只能讀取來自同一來源的窗口和文檔的屬性
    • 同源限制的原因:
      • 比如一個黑客程序,他利用 Iframe 把真正的銀行登錄頁面嵌到他的頁面上,當你使用真實的用戶名,密碼登錄時,他的頁面就可以通過 Javascript 讀取到你的表單中 input 中的內(nèi)容,這樣用戶名,密碼就輕松到手了,同源限制可以避免這種情況的發(fā)生
  4. 什么是跨域,有哪些方式可以跨域?

    • 跨域
      • 指的是跨過同源策略,實現(xiàn)不同域之間進行數(shù)據(jù)交互的過程叫跨域。
    • 跨域的方式
      • 跨域的實現(xiàn)形式主要有 JSONP 方法、CORS方法、降域和 postMessage 等
      • JSONP
        • JSONP 是一種數(shù)據(jù)調(diào)用方式,是解決跨域交互的方法
        • 只能發(fā)送 get 請求
        • 網(wǎng)頁通過在 script 標簽里添加元素,向服務器請求數(shù)據(jù),這種做法不受同源政策的限制,服務器收到請求后,把數(shù)據(jù)放在一個指定的回調(diào)數(shù)中返回
        •   //1.定義出來函數(shù)的appendHtml
            function appendHtml(news){
                var html = '';
                for(var i = 0;i<news.length;i++){
                    html +='<li>' +news[i]+'</li>';
                }
                console.log(html)
                $('.news')innerHtml = html;
            }
            //2.創(chuàng)建script標簽,src地址執(zhí)行后端端口,地址的末尾加個參數(shù) callback = appendHtml
            $(".change").addEventListener("click",function(){
                var script=document.createElement("script");
                script.src='http://localhost:8080/getNews?callback=appendHtml';
                document.head.appendChild("script");
                document.head.removeChild("script");
            })
            //3.服務器在收到請求后,解析參數(shù),計算返回數(shù)據(jù),輸出 appendHtml(data) 字符串
            var www = req.query.callback;
            if(www){
                res.send(www + '(' +JSON.stringify(data)+')');
            }else{
                res.send(data);
            }
            //4.appendHtml(data )會放在 script 標簽里面當做 js 來執(zhí)行,同時調(diào)用 appendHtml() 函數(shù),將 data 作為參數(shù)
          
      • CORS
        • cross origin resource sharing 跨域資源共享。這是 W3C 的標準,是跨域請求的根本解決方法。相比 JSONP 只能發(fā) get 請求,CORS 允許發(fā)任何類型的請求。對于開發(fā)者來說 CORS 通信與同源的 ajax 通信沒有差別,代碼完全一樣。瀏覽器一旦發(fā)現(xiàn) ajax 請求是跨源的,會自動在頭部添加 origin 標簽,用戶無需單獨做操作
        • 工作流程:
          1. 當使用XMLHttpRequest發(fā)送請求時,瀏覽器會檢測到不符合同源策略,于是會加一個請求頭origin
          2. 后臺確認符合策略時,會在返回的數(shù)據(jù)里添加一個響應頭access-control-allow-origin
          3. 瀏覽器判斷該響應頭中是否有origin值,如果有則接收數(shù)據(jù)。如果沒有,則直接駁回。我們無法拿到數(shù)據(jù)
        •   $('.change').addEventListener('click', function () {
                var xhr = new XMLHttpRequest();
                xhr.open('get', 'http://b.jrg.com:8080/getNews', true);
                xhr.send();
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        appendHtml(JSON.parse(xhr.responseText));
                    }
                };
                window.xhr = xhr
            });
            //如果有則瀏覽器會處理響應,我們就可以拿到響應數(shù)據(jù),
            res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080");
            //res.header("Access-Control-Allow-Origin", "*");
          
      • 降域
        • 如果在域名 a.jrg.com 通過 js 操作 b.jrg.com 將會報錯:瀏覽器阻止訪問不同源的 iframe
        •   <iframe src="http://b.jrg.com:8080/b.html" frameborder="0" ></iframe>
          
        • 通過修改 document.domain 來跨域操縱頁面上的 iframe,這樣就能達到我們的目標,讓他們實現(xiàn)跨域交互,document.domain = "jrg.com"
      • Post Message
        • 降域實現(xiàn)跨域通信時要求兩個域屬于同一個父級域名。而 post message 沒有這個限制。一個頁面向另一個頁面發(fā)送 postmessage 消息,如果接收方愿意接收的話(通過 message 語句監(jiān)聽),那么就實現(xiàn)了通信
        • 主頁面 a.html 向 ifame 頁面 b.html 加入 postMessage 信息
          •   $('.main input').addEventListener('input', function(){
                  console.log(this.value);
                  window.frames[0].postMessage(this.value, '*');
              });
              $('.main input').value = e.data;
              console.log(e.data);
              });
            
        • iframe 頁面 b.html 向父頁面 a.htm 加入 postmessage信息
          •   $('#input').addEventListener('input', function(){
                  window.parent.postMessage(this.value, '*');
              });
              window.addEventListener('message',function(e) {
                  $('#input').value = e.data;
                  console.log(e.data);
              });
            
  5. JSONP 的實現(xiàn)原理是什么?

    • JSONP 產(chǎn)生的原因:
      • 因為 Ajax 直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態(tài)頁面、動態(tài)網(wǎng)頁、web 服務、WCF,只要是跨域請求,一律不準。但是在 Web 頁面上調(diào)用 js 文件時則不受是否跨域的影響(不僅如此,我們還發(fā)現(xiàn)凡是擁有 src 這個屬性的標簽都擁有跨域的能力,比如 <\script> 、 <\img><\iframe>
    • JSONP 的實現(xiàn)原理:
      • web 客戶端通過與調(diào)用腳本一模一樣的方式,來調(diào)用跨域服務器上動態(tài)生成的js格式文件(一般以 JSON 為后綴),顯而易見,服務器之所以要動態(tài)生成 JSON 文件,目的就在于把客戶端需要的數(shù)據(jù)裝入進去,客戶端在對 JSON 文件調(diào)用成功之后,也就獲得了自己所需的數(shù)據(jù),剩下的就是按照自己需求進行處理和展現(xiàn)了,這種獲取遠程數(shù)據(jù)的方式看起來非常像 AJAX,但其實并不一樣
      • 為了便于客戶端使用數(shù)據(jù),逐漸形成了一種非正式傳輸協(xié)議,人們把它稱作 JSONP,該協(xié)議的一個要點就是允許用戶傳遞一個 callback 參數(shù)給服務端,然后服務端返回數(shù)據(jù)時會將這 callback 參數(shù)作為函數(shù)名來包裹住 JSON 數(shù)據(jù),這樣客戶端就可以隨意定制自己的函數(shù)來自動處理返回數(shù)據(jù)了
    • 代碼:
      •   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml" >
          <head>
              <title>Untitled Page</title>
              <script type="text/javascript" src=jquery.min.js"></script>
              <script type="text/javascript">
                  jQuery(document).ready(function(){ 
                      $.ajax({
                          type: "get",
                          async: false,
                          url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
                          dataType: "jsonp",
                          jsonp: "callback", //傳遞給請求處理程序或頁面的,用以獲得jsonp回調(diào)函數(shù)名的參數(shù)名(一般默認為:callback)
                          jsonpCallback:"flightHandler", //自定義的jsonp回調(diào)函數(shù)名稱,默認為jQuery自動生成的隨機函數(shù)名,也可以寫"?",jQuery會自動為你處理數(shù)據(jù)
                          success: function(json){
                              alert('您查詢到航班信息:票價: ' + json.price + ' 元,余票: ' + json.tickets + ' 張。');
                          },
                          error: function(){
                              alert('fail');
                          }
                      });
                  });
              </script>
          </head>
          <body>
          </body>
          </html>
        
    • ajax 與 jsonp 的異同:
      • 相同
        • ajax 和 jsonp 這兩種技術在調(diào)用方式上"看起來"很像,目的也一樣,都是請求一個 url,然后把服務器返回的數(shù)據(jù)進行處理,因此 jquery 和 ext 等框架都把 jsonp 作為 ajax 的一種形式進行了封裝
      • 不同
        • ajax 和 jsonp 其實本質上是不同的東西。ajax 的核心是通過 XmlHttpRequest 獲取非本頁內(nèi)容,而 jsonp 的核心則是動態(tài)添加
  6. 手寫一個原生 ajax 請求

    •   const xhr = new XMLHttpRequest();
        // 注意這里其實是可以用四三個參數(shù)的,
        // true表示異步請求
        // false表示同步請求,
        xhr.open('GET', 'http://www.zhengshengliang.com:9999/'); 
      
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) { // 注意readyState大寫
                console.log('請求都相應完畢了');
                if (xhr.status >= 200 && xhr.status < 300) {
                    console.log('相應成功');
                    const res = xhr.responseText; // 你才返回對象,你全家才返回對象 作為http的第四部分,返回的永遠是字符串
                    console.log(typeof res); // "string"
          
                    let obj = window.JSON.parse(res);
                } else if (xhr.status >= 400) {
                    console.log('相應失敗');
                }
            }
        }
      
        xhr.ontimeout = (e) => {
            alert('請求超時了');
        }
      
        xhr.timeout = 3000; // 3000ms超時
        xhr.send();
      
        // 若為異步(true),則先打印1,后打印請求內(nèi)容
        // 若為同步(false),則先打印請求內(nèi)容,后打印1
        console.log(1); 
      
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

  • 創(chuàng)建XMLHttpRequest 對象 所有現(xiàn)代瀏覽器(IE7+、Firefox、Chrome、Safari 以及...
    Miracle_6e4f閱讀 482評論 0 0
  • AJAX 原生js操作ajax 1.創(chuàng)建XMLHttpRequest對象 var xhr = new XMLHtt...
    碧玉含香閱讀 3,563評論 0 7
  • Ajax和XMLHttpRequest 我們通常將Ajax等同于XMLHttpRequest,但細究起來它們兩個是...
    changxiaonan閱讀 2,391評論 0 2
  • 金三銀四已經(jīng)過去了,你升值加薪了嗎?你重新找工作了嗎?你跳槽了嗎?你面試的時候緊張了嗎???你注意過面試管問你的問題...
    小猿圈IT教育閱讀 837評論 0 8
  • 清明節(jié)快到了,不由地想起1995年12月4日發(fā)生的事。如果不是那天命大,恐怕我早已呆在村外某個孤寂瘆人的墳苧中二十...
    積步齋主人閱讀 2,350評論 61 29

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