目錄
一、XMLHttpRequest使用步驟
基本語法
步驟 1:創建 XHR 對象
步驟 2:調用?open()?方法
步驟 3:監聽?loadend?事件
步驟 4:調用?send()?方法
二、完整示例
1. GET 請求(帶查詢參數)
2. POST 請求(提交 JSON 數據)
三、關鍵注意事項
四、URLSearchParams
1.?URLSearchParams?的作用
2. 代碼示例解析
3.?URLSearchParams?常用方法
1.?添加參數
2.?刪除參數
3.?獲取參數值
4.?遍歷參數
4. 處理特殊字符
5. 可選鏈操作符
?五、簡易封裝axios
1. Axios 核心設計
2. 簡易封裝示例
3. AJAX 與 Axios 對比
AJAX(Asynchronous JavaScript and XML)核心原理:通過瀏覽器提供的 XMLHttpRequest(XHR)對象,實現異步通信,無需刷新頁面即可與服務器交換數據。
一、XMLHttpRequest使用步驟
基本語法
- 創建對象 → 配置請求 → 監聽事件 → 發送請求?
const xhr = new XMLHttpRequest()
xhr.open('請求方法', '請求url網址')
xhr.addEventListener('loadend', () => {// 響應結果console.log(xhr.response)
})
xhr.send()
步驟 1:創建 XHR 對象
const xhr = new XMLHttpRequest();
-
作用:初始化一個 XHR 實例,用于后續的請求配置和操作。
-
注意:舊版 IE(< IE7)需使用?
ActiveXObject
,但現代瀏覽器無需兼容處理。
步驟 2:調用?open()
?方法
xhr.open(method, url, async);
-
參數說明:
-
method
:HTTP 方法(GET
、POST
、PUT
?等)。 -
url
:請求的目標地址(支持絕對或相對路徑)。 -
async
:是否異步(默認為?true
,強烈建議使用異步)。
-
-
關鍵點:
-
GET 請求的查詢參數需直接拼接到 URL 中(需手動編碼)。
const params = { page: 1, keyword: 'AJAX' }; const query = new URLSearchParams(params).toString(); // 自動編碼 const url = `https://api.example.com/data?${query}`; xhr.open('GET', url, true);
-
POST 請求的數據在?
send()
?中傳遞(需配合請求頭)。
-
步驟 3:監聽?loadend
?事件
xhr.addEventListener('loadend', function() {// 請求完成(無論成功或失敗)if (xhr.status >= 200 && xhr.status < 300) {console.log('成功:', xhr.responseText);} else {console.error('失敗:', xhr.status, xhr.statusText);}
});
-
loadend
?事件特性:-
在請求完成(包括成功、失敗或取消)后觸發。
-
替代傳統?
onreadystatechange
?的繁瑣狀態判斷。
-
-
響應數據獲取:
-
xhr.responseText
:字符串形式的響應數據(如 JSON、HTML)。 -
xhr.response
:根據?responseType
?自動轉換后的數據(如 JSON 對象)。
-
步驟 4:調用?send()
?方法
xhr.send(body);
-
GET 請求:
send()
?無參數或傳?null
。xhr.send();
-
POST 請求:傳遞請求體數據(需設置?
Content-Type
)。// 設置請求頭(JSON 格式) xhr.setRequestHeader('Content-Type', 'application/json');// 提交 JSON 數據 const postData = JSON.stringify({ username: 'john', age: 25 }); xhr.send(postData);// 提交 FormData(文件上傳) const formData = new FormData(); formData.append('file', fileInput.files[0]); xhr.send(formData);
二、完整示例
1. GET 請求(帶查詢參數)
const xhr = new XMLHttpRequest();// 構建帶查詢參數的 URL
const params = { page: 1, search: 'AJAX 教程' };
const url = `https://api.example.com/data?${new URLSearchParams(params)}`;xhr.open('GET', url, true);xhr.addEventListener('loadend', () => {if (xhr.status === 200) {const data = JSON.parse(xhr.responseText);console.log('數據:', data);} else {console.error(`請求失敗: ${xhr.status}`);}
});xhr.send();
2. POST 請求(提交 JSON 數據)
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/submit', true);// 設置請求頭
xhr.setRequestHeader('Content-Type', 'application/json');xhr.addEventListener('loadend', () => {if (xhr.status === 201) {console.log('提交成功:', xhr.responseText);} else {console.error(`錯誤: ${xhr.status}`);}
});// 提交 JSON 數據
const data = { title: 'XHR 教程', content: '詳細指南' };
xhr.send(JSON.stringify(data));
三、關鍵注意事項
-
查詢參數編碼:
// 手動編碼示例 const keyword = '前端&后端'; const encodedKeyword = encodeURIComponent(keyword); // → '前端%26后端'
-
使用?
URLSearchParams
?或?encodeURIComponent
?避免特殊字符問題。
-
-
POST 請求頭設置:
-
必須根據數據類型設置?
Content-Type
,否則服務器無法正確解析。-
application/json
:JSON 數據。 -
multipart/form-data
:文件上傳。 -
application/x-www-form-urlencoded
:表單數據。
-
-
-
錯誤處理:
-
結合?
loadend
?和?xhr.status
?處理 HTTP 狀態碼。 -
監聽?
error
?和?timeout
?事件處理網絡錯誤和超時。xhr.addEventListener('error', () => {console.error('網絡錯誤'); });xhr.timeout = 5000; // 設置超時時間 xhr.addEventListener('timeout', () => {console.error('請求超時'); });
-
-
同步請求已廢棄:
-
open()
?的第三個參數若設為?false
(同步請求),會導致頁面阻塞,現代開發中禁止使用。
-
XHR和Axios的默認請求頭對比
場景 | XHR(原生) | Axios |
---|---|---|
發送 JSON 數據 | 需手動設置?Content-Type | 自動設置?Content-Type: application/json |
發送 FormData | 自動設置?multipart/form-data | 自動設置?multipart/form-data |
全局默認頭 | 無 | 支持通過?axios.defaults.headers ?配置全局頭 |
攔截器 | 無 | 支持請求/響應攔截器統一管理頭 |
必須聲明Headers的情況
場景 | XHR | Axios |
---|---|---|
發送非表單數據 | 必須手動設置?Content-Type | 自動處理,可手動覆蓋 |
身份認證 | 必須設置?Authorization | 必須設置?Authorization |
跨域自定義頭 | 必須聲明且服務器允許 | 必須聲明且服務器允許 |
文件上傳 | 使用?FormData ?時自動處理 | 使用?FormData ?時自動處理 |
四、URLSearchParams
1.?URLSearchParams
?的作用
URLSearchParams
?是一個 Web API,用于解析、操作 URL 的查詢參數(即??
?后的部分)。它可以:
-
將對象轉換為 URL 查詢字符串(自動編碼特殊字符)。
-
解析現有查詢字符串為鍵值對。
-
動態添加、刪除、遍歷參數。
2. 代碼示例解析
qObj = { key1: 'value1', key2: 'value2' }
const paramsObj = new URLSearchParams(qObj);
const queryString = paramsObj.toString();
xhr.open('GET', `http://example.net/api?${queryString}`);
步驟分解:
-
創建?
URLSearchParams
?實例const paramsObj = new URLSearchParams(qObj);
-
假設?
qObj
?是一個對象(如?{ key1: 'value1', key2: 'value2' }
)。 -
URLSearchParams
?會將其轉換為鍵值對結構。
-
-
生成查詢字符串
const queryString = paramsObj.toString();
-
toString()
?方法將參數轉換為標準的 URL 查詢字符串(如?key1=value1&key2=value2
)。 -
自動處理編碼:空格轉為?
%20
,中文轉為?%E4%B8%AD
?等。
-
-
拼接完整 URL
xhr.open('GET', `http://example.net/api?${queryString}`);
-
最終生成的 URL 示例:
http://example.net/api?key1=value1&key2=value2
-
3.?URLSearchParams
?常用方法
1.?添加參數
paramsObj.append('page', 1); // 添加新參數
paramsObj.append('page', 2); // 允許重復鍵:page=1&page=2
2.?刪除參數
paramsObj.delete('key1'); // 刪除指定鍵
3.?獲取參數值
const value = paramsObj.get('key1'); // 獲取第一個值
const allValues = paramsObj.getAll('page'); // 獲取所有值(數組)
4.?遍歷參數
for (const [key, value] of paramsObj) {console.log(key, value);
}
4. 處理特殊字符
URLSearchParams
?會自動編碼特殊字符,無需手動調用?encodeURIComponent
。
示例:
const params = new URLSearchParams({ city: '北京', q: 'a&b=c' });
console.log(params.toString());
// 輸出:city=%E5%8C%97%E4%BA%AC&q=a%26b%3Dc
5. 可選鏈操作符
JavaScript 中的?
?.
?是可選鏈操作符(Optional Chaining Operator),用于安全地訪問對象的深層屬性。它的作用是:當某個中間屬性為?null
?或?undefined
?時,直接返回?undefined
,而不會拋出錯誤。
代碼示例分析:
// 假設 xhr 是 XMLHttpRequest 的實例
const data = xhr.response?.data;
-
xhr.response
XHR 請求完成后,xhr.response
?是服務器返回的數據。
如果請求未完成或失敗,xhr.response
?可能是?null
?或?undefined
。 -
xhr.response?.data
-
如果?
xhr.response
?存在:繼續訪問?data
?屬性。 -
如果?
xhr.response
?是?null
?或?undefined
:直接返回?undefined
,不會嘗試訪問?.data
。
-
可選鏈操作符(?.
)的核心規則:
場景 | 代碼示例 | 結果 |
---|---|---|
屬性存在 | obj?.prop | 返回?obj.prop |
屬性不存在(null/undefined ) | obj?.prop | 返回?undefined ,不會報錯 |
深層屬性訪問 | obj?.prop1?.prop2 | 逐層檢查,任一中間屬性為?null/undefined ?則返回?undefined |
函數調用 | obj.method?.() | 如果?obj.method ?存在則調用,否則返回?undefined |
?五、簡易封裝axios
Axios 原理:基于?
Promise
?封裝的 HTTP 客戶端庫,底層依賴?XMLHttpRequest
(瀏覽器)或?http
?模塊(Node.js),提供更簡潔、強大的 API。
1. Axios 核心設計
-
適配器模式
-
瀏覽器環境:使用?
XMLHttpRequest
?發送請求。 -
Node.js 環境:使用?
http
?模塊發送請求。 -
統一 API:開發者無需關注底層差異。
-
-
攔截器機制
-
請求攔截器:在請求發送前統一處理(如添加 Token)。
-
響應攔截器:在響應返回后統一處理(如錯誤過濾)。
// 添加請求攔截器 axios.interceptors.request.use(config => {config.headers.Authorization = 'Bearer token';return config; });// 添加響應攔截器 axios.interceptors.response.use(response => response.data, // 提取 data 字段error => Promise.reject(error) );
-
-
配置合并策略
-
全局配置 → 實例配置 → 單次請求配置,優先級遞增。
-
自動處理?
headers
(如?Content-Type
?根據數據類型推斷)。
-
-
Promise 鏈式調用
-
所有請求返回?
Promise
?對象,支持?async/await
。 -
錯誤通過?
.catch()
?或?try/catch
?統一處理。
-
2. 簡易封裝示例
模擬 axios 函數封裝,更深入了解 axios 內部運作原理:
//定義myAxios函數,接收配置對象,返回Promise對象
function myAxios(config) {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest()//判斷有params選項,攜帶查詢參數if (config.params) {//使用URLSearchParams轉換,并攜帶到url上const paramsObj = new URLSearchParams(config.params)const queryString = paramsObj.toString()config.url += `?${queryString}`}//發起XHR請求,默認請求方法為GETxhr.open(config.method || 'GET', config.url)xhr.addEventListener('loadend', () => {//調用成功/失敗的處理程序if (xhr.status >= 200 && xhr.status < 300) {resolve(JSON.parse(xhr.response))}else {reject(new Error(xhr.response))}})//判斷有data選項,攜帶請求體if (config.data) {xhr.setRequestHeader('Content-Type', 'application/json')xhr.send(JSON.stringify(config.data))}else {xhr.send()}})
}
3. AJAX 與 Axios 對比
特性 | AJAX(原生 XHR) | Axios |
---|---|---|
底層實現 | 直接操作?XMLHttpRequest ?對象 | 封裝 XHR 或 Node.js?http ?模塊,提供統一 API |
異步處理 | 回調函數 | 基于?Promise ,支持?async/await |
數據轉換 | 手動解析 JSON、XML 等格式 | 自動轉換 JSON 數據 |
攔截器 | 需手動實現 | 內置請求/響應攔截器 |
取消請求 | 使用?xhr.abort() | 支持?CancelToken ?和?AbortController |
跨域處理 | 需服務端配合 CORS 或 JSONP | 自動處理 CORS,支持?withCredentials ?配置 |
代碼簡潔性 | 冗余,需手動處理細節 | 鏈式調用,配置化 API |