前端開發離不開跟后端打交道,HTTP 請求就是這座橋梁。JavaScript 提供了好幾種方式來發請求,從老牌的 XMLHttpRequest (XHR) 到現代的 Fetch API,再到各種好用的第三方庫(像 Axios、Ky、Superagent)。咱們一個一個聊清楚,帶代碼示例,講講優缺點和實際場景,最后再看看未來趨勢。
1. XMLHttpRequest (XHR):老大哥還在用
1.1 啥是 XHR?
XHR 是瀏覽器內置的 API,最早微軟在 IE5 搞出來的,后來成了 Web 標準。雖然現在 Fetch 更時髦,但 XHR 在老項目或者需要兼容古老瀏覽器的場景里還挺常見。
1.2 特點
- 異步支持:可以異步發請求,通過事件監聽處理結果。
- 靈活:支持 GET、POST、PUT 等方法,能處理 JSON、文件、甚至二進制數據。
- 兼容性:幾乎所有瀏覽器(包括 IE)都支持。
- 缺點:代碼寫起來有點繁瑣,回調風格容易搞成“回調地獄”。
1.3 怎么用?
來看個簡單的 GET 請求:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true); // true 表示異步
xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {console.log(JSON.parse(xhr.responseText)); // 成功拿到數據} else if (xhr.readyState === 4) {console.error('出錯了:', xhr.statusText); // 錯誤處理}
};
xhr.onerror = function () {console.error('網絡掛了'); // 網絡錯誤
};
xhr.send();
1.4 POST 請求
如果要發 POST 請求,比如提交個表單數據:
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/submit', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {console.log('成功:', JSON.parse(xhr.responseText));} else if (xhr.readyState === 4) {console.error('出錯了:', xhr.statusText);}
};
const data = JSON.stringify({ name: '小明', age: 25 });
xhr.send(data);
1.5 高級點玩法
- 超時:
xhr.timeout = 5000
設置 5 秒超時。 - 進度監聽:用
xhr.onprogress
監聽大文件上傳/下載進度。 - 取消請求:
xhr.abort()
直接干掉請求。
1.6 優缺點
- 優點:原生支持,兼容性無敵,能監聽進度。
- 缺點:代碼啰嗦,回調太多,現代項目用起來有點老土。
2. Fetch API:現代前端的標配
2.1 啥是 Fetch?
Fetch 是瀏覽器的新 API,2015 年開始推廣,基于 Promise 設計,寫起來比 XHR 清爽多了。現在基本是前端發請求的首選。
2.2 特點
- Promise 風格:支持 async/await,代碼簡潔。
- 流式處理:可以用 ReadableStream 處理大文件。
- 現代化:API 設計直觀,配置簡單。
- 缺點:不會自動拋 HTTP 錯誤(像 404、500),得自己檢查;不支持進度事件。
2.3 基本用法
簡單的 GET 請求:
fetch('https://api.example.com/data').then(response => {if (!response.ok) {throw new Error(`HTTP 錯誤! 狀態碼: ${response.status}`);}return response.json();}).then(data => console.log(data)).catch(error => console.error('出錯了:', error));
用 async/await 更清爽:
async function fetchData() {try {const response = await fetch('https://api.example.com/data');if (!response.ok) {throw new Error(`HTTP 錯誤! 狀態碼: ${response.status}`);}const data = await response.json();console.log(data);} catch (error) {console.error('出錯了:', error);}
}
fetchData();
2.4 POST 請求
發個 POST 請求:
async function postData() {try {const response = await fetch('https://api.example.com/submit', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({ name: '小明', age: 25 }),});if (!response.ok) {throw new Error(`HTTP 錯誤! 狀態碼: ${response.status}`);}const data = await response.json();console.log('成功:', data);} catch (error) {console.error('出錯了:', error);}
}
postData();
2.5 高級玩法
- 流式處理:處理大文件或流式數據:
async function streamData() {const response = await fetch('https://api.example.com/stream');const reader = response.body.getReader();const decoder = new TextDecoder();while (true) {const { done, value } = await reader.read();if (done) break;console.log(decoder.decode(value));} }
- 取消請求:用
AbortController
:const controller = new AbortController(); fetch('https://api.example.com/data', { signal: controller.signal }).then(response => response.json()).then(data => console.log(data)).catch(error => console.error('出錯了:', error)); setTimeout(() => controller.abort(), 3000); // 3秒后取消
2.6 優缺點
- 優點:語法簡潔,Promise 好用,支持流式處理,跟現代 JS 配合天衣無縫。
- 缺點:得手動檢查 HTTP 狀態碼,IE 不支持,沒進度事件。
3. 熱門請求庫:省心省力
原生的 XHR 和 Fetch 雖然好,但有時候寫起來還是麻煩。第三方庫把這些都封裝得更簡單,下面聊聊幾個 2025 年還很火的庫。
3.1 Axios:萬金油選擇
啥是 Axios?
Axios 是最流行的 HTTP 客戶端,支持瀏覽器和 Node.js,基于 Promise,功能強大,社區活躍。
特點:
- 自動轉 JSON 數據。
- 支持請求/響應攔截器(比如加 token)。
- 支持取消請求、超時。
- 兼容性好,連 IE 都支持。
- GitHub Star(2025 年):大概 100k+。
基本用法:
import axios from 'axios';async function fetchWithAxios() {try {const response = await axios.get('https://api.example.com/data');console.log(response.data);} catch (error) {console.error('出錯了:', error.message);}
}// POST 請求
async function postWithAxios() {try {const response = await axios.post('https://api.example.com/submit', {name: '小明',age: 25,});console.log('成功:', response.data);} catch (error) {console.error('出錯了:', error.message);}
}
攔截器(超實用):
axios.interceptors.request.use(config => {config.headers.Authorization = `Bearer ${token}`;return config;
});axios.interceptors.response.use(response => response,error => {console.error('全局錯誤:', error);return Promise.reject(error);}
);
優點:
- API 簡單,功能全。
- 支持全局配置,適合大項目。
- 自動處理 HTTP 錯誤。
缺點:
- 得引入庫,增加點體積(壓縮后 ~20KB)。
- 小項目可能用不上這么多功能。
3.2 Ky:輕量又時髦
啥是 Ky?
Ky 是基于 Fetch 的輕量庫,專為現代瀏覽器設計,API 優雅,體積小。
特點:
- 基于原生 Fetch,無需 polyfill。
- API 直觀,比如
ky.get().json()
。 - 體積超小(壓縮后 ~5KB)。
- 支持超時、重試、JSON 自動解析。
基本用法:
import ky from 'ky';async function fetchWithKy() {try {const data = await ky.get('https://api.example.com/data').json();console.log(data);} catch (error) {console.error('出錯了:', error);}
}// POST 請求
async function postWithKy() {try {const data = await ky.post('https://api.example.com/submit', {json: { name: '小明', age: 25 },}).json();console.log('成功:', data);} catch (error) {console.error('出錯了:', error);}
}
重試機制:
const data = await ky.get('https://api.example.com/data', {retry: 3,timeout: 5000,
}).json();
優點:
- 超輕量,API 優雅,適合小項目。
- 學習成本低,現代瀏覽器完美支持。
缺點:
- 不支持 IE。
- 功能比 Axios 簡單點,攔截器支持有限。
3.3 Superagent:鏈式調用很酷
啥是 Superagent?
Superagent 是個輕量 HTTP 客戶端,支持瀏覽器和 Node.js,鏈式調用風格很獨特,適合快速上手。
特點:
- 鏈式 API(像
.get().query()
)。 - 支持文件上傳、超時、認證。
- 體積適中(壓縮后 ~15KB)。
基本用法:
import request from 'superagent';async function fetchWithSuperagent() {try {const response = await request.get('https://api.example.com/data');console.log(response.body);} catch (error) {console.error('出錯了:', error.message);}
}// POST 請求
async function postWithSuperagent() {try {const response = await request.post('https://api.example.com/submit').send({ name: '小明', age: 25 });console.log('成功:', response.body);} catch (error) {console.error('出錯了:', error.message);}
}
優點:
- 鏈式調用寫起來爽,代碼可讀性高。
- 支持多種數據格式。
缺點:
- 社區沒 Axios 活躍。
- 功能比 Axios 少點。
3.4 其他好用的
- SWR:React 專用的數據獲取庫,帶緩存,超適合動態數據場景。
import useSWR from 'swr'; const fetcher = url => fetch(url).then(res => res.json()); const { data, error } = useSWR('https://api.example.com/data', fetcher);
- React Query (TanStack Query):復雜應用的利器,數據同步和狀態管理一流。
- Alova:新興庫,支持請求策略(緩存、重試),跟 Vue/React 配合好。
4. 對比:選哪個好?
工具 | 原生? | Promise? | 體積 | 攔截器 | 流式處理 | 取消請求 | 兼容性 | 適合場景 |
---|---|---|---|---|---|---|---|---|
XHR | 是 | 否 | 無需引入 | 不支持 | 支持 | 支持 | 超強(包括 IE) | 老項目、兼容性要求高 |
Fetch | 是 | 是 | 無需引入 | 不支持 | 支持 | 支持 | 現代瀏覽器 | 現代 Web 開發 |
Axios | 否 | 是 | ~20KB | 支持 | 不支持 | 支持 | 超強(包括 IE) | 企業級、復雜需求 |
Ky | 否 | 是 | ~5KB | 有限 | 支持 | 支持 | 現代瀏覽器 | 輕量項目、現代瀏覽器 |
Superagent | 否 | 是 | ~15KB | 有限 | 不支持 | 支持 | 好 | 快速開發、中小型項目 |
選啥?
- 小項目:Fetch 或 Ky,簡單輕量。
- 大項目:Axios,功能全,省心。
- React 項目:SWR 或 React Query,數據管理更方便。
- 兼容 IE:用 XHR 或 Axios。
- Web3/實時:Fetch 配合 WebSocket 更靈活。
5. 實戰:寫個請求工具類
下面是個基于 Fetch 和 Axios 的工具類,方便復用,支持 GET、POST、錯誤處理和超時:
class HttpClient {constructor(baseURL) {this.baseURL = baseURL;this.axiosInstance = axios.create({baseURL,timeout: 10000,});}async fetchRequest(method, url, data = null, options = {}) {try {const response = await fetch(`${this.baseURL}${url}`, {method,headers: {'Content-Type': 'application/json',...options.headers,},body: data ? JSON.stringify(data) : null,...options,});if (!response.ok) {throw new Error(`HTTP 錯誤! 狀態碼: ${response.status}`);}return await response.json();} catch (error) {console.error('Fetch 出錯了:', error);throw error;}}async axiosRequest(method, url, data = null) {try {const response = await this.axiosInstance({ method, url, data });return response.data;} catch (error) {console.error('Axios 出錯了:', error.message);throw error;}}get(url, options = {}) {return this.fetchRequest('GET', url, null, options);}post(url, data, options = {}) {return this.fetchRequest('POST', url, data, options);}axiosGet(url) {return this.axiosRequest('get', url);}axiosPost(url, data) {return this.axiosRequest('post', url, data);}
}// 用法
const client = new HttpClient('https://api.example.com');async function main() {try {const fetchData = await client.get('/data');console.log('Fetch GET:', fetchData);const axiosData = await client.axiosPost('/submit', { name: '小明' });console.log('Axios POST:', axiosData);} catch (error) {console.error('出錯了:', error);}
}
main();
6. 注意事項
- 錯誤處理:Fetch 不會自動拋 404、500,得自己檢查;Axios 自動拋。
- 超時:Fetch 用
AbortController
,Axios 直接配timeout
。 - 安全:
- 用 HTTPS,防止數據泄露。
- 正確設置
Content-Type
和Accept
頭。 - 防 XSS/CSRF,檢查 CORS 配置。
- 性能:
- 用 SWR 或瀏覽器 Cache API 緩存數據。
- 壓縮請求體(比如 Gzip)。
- 用 CDN 加速靜態資源。
- 調試:
- 瀏覽器 DevTools 的 Network 面板。
- Postman 或者 Insomnia 測試 API。
- Axios 的攔截器可以打日志。
7. 未來趨勢
- GraphQL:越來越多人用 GraphQL 替代 REST,推薦 Apollo Client 或 urql。
- Server Components:React 19 和 Next.js 15 的服務器組件減少客戶端請求,性能更好。
- WebTransport:新 API,可能取代部分 HTTP 請求,延遲更低。
- AI 輔助:AI 工具(像 Vercel 的 v0)可能自動生成請求代碼,優化 API 調用。
8. 總結
- XHR:老項目或兼容 IE 用,代碼有點煩。
- Fetch:現代標配,Promise 和流式處理很強,但得手動處理錯誤。
- Axios:大項目首選,功能全,社區強。
- Ky:小項目利器,輕量又好用。
- Superagent:鏈式調用爽,適合快速開發。
根據項目需求選工具:小項目用 Fetch/Ky,大項目選 Axios,React 開發試試 SWR 或 React Query。想動手試試?可以拿上面的工具類改改,調個公開 API(比如 JSONPlaceholder)練練手!
點個收藏,關注前端結城,一起用代碼點亮前端世界!🚀