什么是Ajax
Ajax(Asynchronous JavaScript And XML),實際上就是異步的JavaScript和XML,Ajax是一種概念,指無需刷新頁面即可與服務器通信的技術。
記住:Ajax是一個技術統稱,包含了很多技術,不是特指某一種技術,也不是發送請求的一種方式。XMLHttpRequest 是實現Ajax的一種方式。
異步JavaScript
可以異步地向服務器端發送請求,在等待響應的過程中,不會阻塞當前頁面。瀏覽器還可以做自己的事情,直到成功獲取響應后,瀏覽器才開始處理響應數據。
XML
只是一種前后端傳輸數據的格式,現在主要用JSON。
應用場景
Ajax通常用于創建快速響應的Web程序,例如:
- 動態更新內容:比如在微博中,用戶發布新評論可以實時更新到頁面上,不需要刷新整個頁面。
- 自動完成功能:利用百度搜索引擎時,Ajax可以根據用戶輸入的內容,及時向服務器發送請求并返回匹配的結果列表,提供反饋。
- 分頁和無限滾動:在展示博客文章等內容時,Ajax可以在用戶滾動到底部時自動加載更多內容,或點擊分頁按鈕來加載特定數據塊,而不是一次性加載。
實現Ajax
我們來看一組代碼:
json
代碼解讀
復制代碼//test.josn的代碼
{
"reply":"我收到啦!"
}
ini
代碼解讀
復制代碼const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
}
};
xhr.open('GET', 'text.json', true);
xhr.send(null);
執行結果如下:
這里有一點需要注意:JSON文件中的對象鍵名一定要用雙引號包裹,如果屬性值里有字符串,也需要用雙引號包裹。
執行過程
1.創建xhr對象
ini
代碼解讀
復制代碼const xhr = new XMLHttpRequest();
2.利用onreadystatechange屬性,封裝一個函數,來監聽readyState的變化
ini
代碼解讀
復制代碼xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if (xhr.status >= 200 && xhr.status < 300 ){
console.log(xhr.responseText);
}
};
2.1當xhr對象執行發送數據時,有五種狀態:
2.2判斷Http狀態碼
lua
代碼解讀
復制代碼if (xhr.status >= 200 && xhr.status < 300 ){
console.log(xhr.responseText);
}
Ajax的狀態碼為4是不夠的,這只能表示收到了服務器端所有的響應的數據,但不能保證這個數據是正確的。
所以還需要判斷Http的狀態碼,確保xhr對象的statue屬性值在200~300之間。
3.準備發送請求
kotlin
代碼解讀
復制代碼xhr.open('GET','text.json',ture);
第一個參數是請求方式:method(“GET”或“POST”);第二個參數是:url(文件在服務器上的位置);第三個參數是:async(true:異步,false:同步)。
4.發送請求
csharp
代碼解讀
復制代碼xhr.send(null)
注意:send()的參數是通過請求體攜帶的數據,而GET請求是通過請求頭攜帶數據的,所以要把send()參數設置為null。
Fetch
Fetch 出現在ES6,使用了ES6中的promise對象。是XMLHttpRequest的替代品。
大多數時候我們會將Ajax和Fetch放在一起比較,實際上比的是Ajax中的XMLHttpRequest和Fetch。
注意:Fetch是一個API,是基于Promise真實存在的。
Fetch的特點
- 基于Promise:Fetch會返回一個Promsie對象,使得異步操作更加簡潔和理解。還可以通過鏈式調用
.then()
和.catch()
,可以更加清晰處理響應和錯誤。 - 簡潔的API:Fetch有一套簡潔的方法來執行HTTP請求。
- 支持跨域請求:Fetch默認支持跨域請求,但需要在服務器端配置CORS(跨域資源共享)。通過設置
credentials
屬性,還可以在跨域請求中發送cookies。 - 支持流式輸出:Fetch支持流式輸出,讓大型響應或請求時更高效。
發送請求
Fetch 發送請求和Ajax相比較為簡單,來看個POST請求:
javascript
代碼解讀
復制代碼fetch('https://example.com/api/data', {
method: 'POST', // 請求方法
headers: {
'Content-Type': 'application/json' // 指定發送的數據格式
},
body: JSON.stringify({ // 將 JavaScript 對象轉換為 JSON 字符串
name: 'Kimi',
age: 25
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error('Fetch error:', err));
以上代碼就是向特定的端點發送包含用戶信息的POST請求,設定了請求頭和請求體來明確信息。
Axios
Axios是一個隨著Vue興起而被廣泛使用的,Vue大多數項目中都是利用Axios來發起請求的。
注意:Axios不是一個思想,也不是一個技術。而是一個基于Promise封裝的網絡請求庫,是基于XMLHttpRequest進行二次封裝。
那有沒有想過,為什么Axios是基于XMLHttpRequest的而不是Fetch?
原因有以下幾點:
- 歷史性:在Axios首次開發時,Fetch還沒有被一個普遍使用,因為它是隨著ES6誕生的。而XMLHttpRequest已經使用多年,幾乎所有瀏覽器都支持。
- 自動轉換JSON數據:Axios可以自動將傳入傳出的數據轉換成JSON格式,但早期的Fetch需要手動轉換。
- 請求和響應攔截器:Axios允許在請求發送前或響應被處理之前對其進行修改或干預,這有利于添加通用認證令牌。Fetch本身不支持這種功能。
從Axios官網我們可以了解到Axios有以下特點:
從瀏覽器創建 XMLHttpRequests
從 node.js 創建 http 請求
支持 Promise API
攔截請求和響應
轉換請求和響應數據
取消請求
超時處理
查詢參數序列化支持嵌套項處理
自動將請求體序列化為:
- JSON (
application/json
) - Multipart / FormData (
multipart/form-data
) - URL encoded form (
application/x-www-form-urlencoded
)
- JSON (
將 HTML Form 轉換成 JSON 進行請求
自動轉換JSON數據
獲取瀏覽器和 node.js 的請求進度,并提供額外的信息(速度、剩余時間)
為 node.js 設置帶寬限制
兼容符合規范的 FormData 和 Blob(包括 node.js)
客戶端支持防御XSRF 所以,Axios是XHR的一個子集,而XHR又是Ajax的一個子集。我們在一開始就說過Axios是一個庫,所以需要在使用時引入。
看個POST請求:
javascript
代碼解讀
復制代碼axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
總結
網絡請求 | 特點 |
---|---|
Ajax | 一種技術統稱,主要利用XHR實現網絡請求 |
Fetch | 具體API,基于promise,實現網絡請求 |
Axios | 一個封裝庫,基于XHR封裝,推薦使用 |