AJAX原理及常見面試題


引語

AJAX 即 Asynchronous JavaScript And XML(異步JavaScript和XML),是指一種創建交互式網頁應用的網頁開發技術。

AJAX 是一種用於創建快速動態網頁的技術。它可以令開發者只向服務器獲取數據(而不是圖片,html文檔等資源),互聯網資源的傳輸變得前所未有的輕量級和純粹,這激發了廣大開發者的創造力,使各式各樣功能強大的網絡站點,和互聯網應用如雨后春筍一般冒出,不斷帶給人驚喜。

 

一、什么是AJAX

Ajax是一種異步請求數據的web開發技術,對於改善用戶的體驗和頁面性能很有幫助。簡單地說,在不需要重新刷新頁面的情況下,Ajax 通過異步請求加載后台數據,並在網頁上呈現出來。常見運用場景有表單驗證是否登入成功、百度搜索下拉框提示和快遞單號查詢等等。

Ajax的目的是提高用戶體驗,較少網絡數據的傳輸量。同時,由於AJAX請求獲取的是數據而不是html文檔,因此它也節省了網絡帶寬,讓互聯網用戶的網絡沖浪體驗變得更加順暢。

 

二、AJAX原理是什么

Ajax相當於在用戶和服務器之間加了一個中間層,使用戶操作與服務器響應異步化。並不是所有的用戶請求都提交給服務器,像一些數據驗證和數據處理等都交給Ajax引擎自己來做,只有確定需要從服務器讀取新數據時再由Ajax引擎代為向服務器提交請求。

Ajax的原理簡單來說通過XmlHttpRequest對象來向服務器發送異步請求,從服務器獲得數據,然后用JavaScript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數據。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所了解。

XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是JavaScript可以及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。

 

三、AJAX的使用

1. 創建Ajax核心對象XMLHttpRequest(記得考慮兼容性)

let xhr = null; if (window.`XMLHttpRequest`) {// 兼容 IE7+, Firefox, Chrome, Opera, Safari xhr = new `XMLHttpRequest`(); } else {// 兼容 IE6, IE5 xhr = new ActiveXObject("Microsoft.XMLHTTP"); } 

2. 向服務器發送請求

xhr.open(method, url, async); send(string);//`POST`請求時才使用字符串參數,否則不用帶參數。
  • method:請求的類型;GET 或 POST
  • url:文件在服務器上的位置
  • async:true(異步)或 false(同步)

注意:POST請求一定要設置請求頭的格式內容

xhr.open("`POST`", "test.html", true); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.send("fname=Henry&lname=Ford"); //`POST`請求參數放在send里面,即請求體

一個Promise對象實現的 Ajax 操作的例子:

const getjsON = function(url) { const promise = new Promise(function(resolve, reject){ const handler = function() { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; const client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); }); return promise; }; getJSON("/posts.json").then(function(json) { console.log('Contents: ' + json); }, function(error) { console.error('出錯了', error); });

3. 服務器響應處理(區分同步跟異步兩種情況)

responseText 獲得字符串形式的響應數據。
responseXML 獲得XML 形式的響應數據。

同步處理
xhr.open("`GET`","info.txt",false); xhr.send(); document.`GET`ElementById("mydiv").innerHTML = xhr.responseText; //獲取數據直接顯示在頁面上
異步處理(推薦)

相對來說比較復雜,要在請求狀態改變事件中處理。

xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200){ document.`GET`ElementById("mydiv").innerHTML = xhr.responseText; } } 
什么是readyState?

readyState是XMLHttpRequest對象的一個屬性,用來標識當前XMLHttpRequest對象處於什么狀態。
readyState總共有5個狀態值,分別為0~4,每個值代表了不同的含義:

  • 0:未初始化 — 尚未調用.open()方法;
  • 1:啟動 — 已經調用.open()方法,但尚未調用.send()方法;
  • 2:發送 — 已經調用.send()方法,但尚未接收到響應;
  • 3:接收 — 已經接收到部分響應數據;
  • 4:完成 — 已經接收到全部響應數據,而且已經可以在客戶端使用了;
什么是status?

HTTP狀態碼(status)由三個十進制數字組成,第一個十進制數字定義了狀態碼的類型,后兩個數字沒有分類的作用。HTTP狀態碼共分為5種類型:

  • 1xx(臨時響應):表示臨時響應並需要請求者繼續執行操作的狀態碼。
  • 2xx(成功):表示成功處理了請求的狀態碼。
  • 3xx(重定向):表示要完成請求,需要進一步操作。通常,這些狀態代碼用來重定向。
  • 4xx(請求錯誤):這些狀態碼表示請求可能出錯,妨礙了服務器的處理。
  • 5xx(服務器錯誤):這些狀態碼表示服務器在嘗試處理請求時發生內部錯誤。這些錯誤可能是服務器本身的錯誤,而不是請求出錯。
常見的狀態碼

僅記錄在 RFC2616 上的 HTTP 狀態碼就達 40 種,若再加上 WebDAV(RFC4918、5842)和附加 HTTP 狀態碼 (RFC6585)等擴展,數量就達 60 余種。接下來,我們就介紹一下這些具有代表性的一些狀態碼。

  • 200 表示從客戶端發來的請求在服務器端被正常處理了。
  • 204 表示請求處理成功,但沒有資源返回。
  • 301 表示永久性重定向。該狀態碼表示請求的資源已被分配了新的URI,以后應使用資源現在所指的URI。
  • 302 表示臨時性重定向。
  • 304 表示客戶端發送附帶條件的請求時(指采用GET方法的請求報文中包含if-matched,if-modified-since,if-none-match,if-range,if-unmodified-since任一個首部)服務器端允許請求訪問資源,但因發生請求未滿足條件的情況后,直接返回304Modified(服務器端資源未改變,可直接使用客戶端未過期的緩存)
  • 400 表示請求報文中存在語法錯誤。當錯誤發生時,需修改請求的內容后再次發送請求。
  • 401 表示未授權(Unauthorized),當前請求需要用戶驗證
  • 403 表示對請求資源的訪問被服務器拒絕了
  • 404 表示服務器上無法找到請求的資源。除此之外,也可以在服務器端拒絕請求且不想說明理由時使用。
  • 500 表示服務器端在執行請求時發生了錯誤。也有可能是Web應用存在的bug或某些臨時的故障。
  • 503 表示服務器暫時處於超負載或正在進行停機維護,現在無法處理請求。

4. GET和POST請求數據區別

  1. GET在瀏覽器回退時是無害的,而POST會再次提交請求。
  2. GET產生的URL地址可以被Bookmark,而POST不可以。
  3. GET請求會被瀏覽器主動cache,而POST不會,除非手動設置。
  4. GET請求只能進行url編碼,而POST支持多種編碼方式。
  5. GET請求參數會被完整保留在瀏覽器歷史記錄里,而POST中的參數不會被保留。
  6. GET請求在URL中傳送的參數是有長度限制的,而POST么有。
  7. 對參數的數據類型,GET只接受ASCII字符,而POST沒有限制。
  8. GET比POST更不安全,因為參數直接暴露在URL上,所以不能用來傳遞敏感信息。
  9. GET參數通過URL傳遞,POST放在Request body中。

GET和POST使用場景:
若符合下列任一情況,則推薦用POST方法:

  • 請求的結果有持續性的副作用,例如,數據庫內添加新的數據行。
  • 若使用GET方法,則表單上收集的數據可能讓URL過長。
  • 要傳送的數據不是采用7位的ASCII編碼。

若符合下列任一情況,則推薦用GET方法:

  • 請求是為了查找資源,HTML表單數據僅用來幫助搜索。
  • 請求結果無持續性的副作用。
  • 收集的數據及HTML表單內的輸入字段名稱的總長不超過1024個字符。

資源搜索網站大全 https://www.renrenfan.com.cn 廣州VI設計公司https://www.houdianzi.com

四、常見AJAX面試題

什么是AJAX?AJAX作用是什么?

詳見本文內容=>

原生JavaScript AJAX請求有幾個步驟?分別是什么?
//創建 XMLHttpRequest 對象 var xhr = new XMLHttpRequest(); //發送信息至服務器時內容編碼類型 xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); //接受服務器響應數據 xhr.onreadystatechange = function () { if (xhr.readyState == 4 && (xhr.status == 200) { // let data = xhr.responseText; } }; //規定請求的類型、URL 以及是否異步處理請求。 xhr.open('GET',url,true); //發送請求 xhr.send(null); 
JSON字符串和JSON對象的相互轉換
//字符串轉對象 JSON.parse(json) eval('(' + jsonstr + ')') // 對象轉字符串 JSON.stringify(json)
AJAX幾種請求方式?他們的優缺點?

詳見本文內容=>

HTTP常見狀態碼有哪些?

詳見本文內容=>

什么情況造成跨域(什么是同源策略)?

同源策略是瀏覽器的一個安全功能,不同源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方資源。所以xyz.com下的js腳本采用Ajax讀取abc.com里面的文件數據是會被拒絕的。

同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用於隔離潛在惡意文件的重要安全機制。

舉個例子:

不受同源策略限制的情況:

  1. 頁面中的鏈接,重定向以及表單提交是不會受到同源策略限制的。
  2. 跨域資源的引入是可以的。但是js不能讀寫加載的內容。如嵌入到頁面中的<script src="..."></script>,<img>,<link>,<iframe>等。

跨域解決方案有哪些?

  • JSONP 只能解決GET跨域(問的最多)
    原理:動態創建一個script標簽。利用script標簽的src屬性不受同源策略限制。因為所有的src屬性和href屬性都不受同源策略限制。可以請求第三方服務器數據內容。
    步驟:

    1. 創建一個script標簽 2. script的src屬性設置接口地址 3. 接口參數,必須要帶一個自定義函數名 要不然后台無法返回數據。 4. 通過定義函數名去接收后台返回數據 ```js //去創建一個script標簽 let script = document.createElement("script"); //script的src屬性設置接口地址 並帶一個callback回調函數名稱 script.src = "http://127.0.0.1:8888/index.php?callback=jsonpCallback"; //插入到頁面 document.head.appendChild(script); //通過定義函數名去接收后台返回數據 function jsonpCallback(data){ //注意:jsonp返回的數據是json對象可以直接使用 //ajax 取得數據是json字符串需要轉換成json對象才可以使用。 } ``` 
  • CORS:跨域資源共享
    原理:服務器設置Access-Control-Allow-OriginHTTP響應頭之后,瀏覽器將會允許跨域請求
    限制:瀏覽器需要支持HTML5,可以支持POST,PUT等方法兼容ie9以上
    需要后台設置

    Access-Control-Allow-Origin: *              //允許所有域名訪問,或者 Access-Control-Allow-Origin: http://a.com //只允許所有域名訪問
  • 設置 document.domain
    原理:相同主域名不同子域名下的頁面,可以設置document.domain讓它們同域
    限制:同域document提供的是頁面間的互操作,需要載入iframe頁面

    // URL http://a.com/foo var ifr = document.createElement('iframe'); ifr.src = 'http://b.a.com/bar'; ifr.onload = function(){ var ifrdoc = ifr.contentDocument || ifr.contentWindow.document; ifrdoc.getElementsById("foo").innerHTML); }; ifr.style.display = 'none'; document.body.appendChild(ifr);
  • ES5 postMessage
    ES5新增的 postMessage() 方法允許來自不同源的腳本采用異步方式進行有限的通信,可以實現跨文本檔、多窗口、跨域消息傳遞.
    語法:

    postMessage(data,origin)
  • 用Apache做轉發(逆向代理),讓跨域變成同域
 

五、結語

其實通過 XMLHttpRequest或者封裝后的框架進行網絡請求,這種方式已經有點老舊了,配置和調用方式非常混亂,近幾年剛剛出來的Fetch提供了一個更好的替代方法,它不僅提供了一種簡單,合乎邏輯的方式來跨網絡異步獲取資源,而且可以很容易地被其他技術使用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM