前端JavaScript?6?種主流接口請(qǐng)求技術(shù)全解
本文全面講解 6 種主流接口請(qǐng)求方案,涵蓋原生 API 與流行庫實(shí)現(xiàn),提供可直接復(fù)用的代碼模板與最佳實(shí)踐指南。
一、XMLHttpRequest(原生方案)
1.1 基礎(chǔ)使用
const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://api.example.com/data', true); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { console.log(JSON.parse(xhr.responseText)); } else { console.error('請(qǐng)求失敗:', xhr.statusText); } }; xhr.onerror = function() { console.error('網(wǎng)絡(luò)錯(cuò)誤'); }; xhr.send();
1.2 高級(jí)配置
// POST 請(qǐng)求示例 xhr.open('POST', 'https://api.example.com/submit'); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify({ name: 'John', age: 25 })); // 超時(shí)控制 xhr.timeout = 5000; xhr.ontimeout = function() { console.error('請(qǐng)求超時(shí)'); };
優(yōu)點(diǎn):
- 瀏覽器原生支持
- 精細(xì)控制請(qǐng)求過程
缺點(diǎn):
- 回調(diào)地獄問題
- 需手動(dòng)處理響應(yīng)解析
- 缺乏 Promise 支持
二、Fetch API(現(xiàn)代標(biāo)準(zhǔn))
2.1 基礎(chǔ)請(qǐng)求
fetch('https://api.example.com/data') .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => console.log(data)) .catch(error => console.error('請(qǐng)求失敗:', error));
2.2 高級(jí)配置
// POST 請(qǐng)求配置 fetch('https://api.example.com/submit', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer token' }, body: JSON.stringify({ title: 'New Post' }), credentials: 'include', // 攜帶 cookies mode: 'cors' // 跨域模式 }); // 取消請(qǐng)求 const controller = new AbortController(); setTimeout(() => controller.abort(), 5000); fetch(url, { signal: controller.signal }) .catch(err => { if (err.name === 'AbortError') { console.log('請(qǐng)求被取消'); } });
優(yōu)勢(shì):
- Promise 鏈?zhǔn)秸{(diào)用
- 內(nèi)置響應(yīng)解析方法
- 支持流式數(shù)據(jù)處理
局限:
- 默認(rèn)不攜帶 cookies
- 錯(cuò)誤處理需要額外判斷
- 不支持超時(shí)直接配置
三、Axios(流行庫)
3.1 基礎(chǔ)用法
import axios from 'axios'; // GET 請(qǐng)求 axios.get('/user?ID=12345') .then(response => console.log(response.data)) .catch(error => console.error(error)); // POST 請(qǐng)求 axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }, { headers: { 'X-Custom-Header': 'value' } });
3.2 全局配置
// 創(chuàng)建實(shí)例 const api = axios.create({ baseURL: 'https://api.example.com', timeout: 10000, headers: { 'X-Requested-With': 'XMLHttpRequest' } }); // 請(qǐng)求攔截 api.interceptors.request.use(config => { config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`; return config; }); // 響應(yīng)攔截 api.interceptors.response.use( response => response.data, error => { if (error.response?.status === 401) { window.location = '/login'; } return Promise.reject(error); } );
核心特性:
- 自動(dòng)轉(zhuǎn)換 JSON 數(shù)據(jù)
- 客戶端 XSRF 防護(hù)
- 并發(fā)請(qǐng)求處理
- 請(qǐng)求取消支持
四、jQuery Ajax(傳統(tǒng)方案)
4.1 基礎(chǔ)實(shí)現(xiàn)
$.ajax({ url: 'https://api.example.com/data', method: 'GET', dataType: 'json', success: function(data) { console.log(data); }, error: function(xhr, status, error) { console.error(error); } });
4.2 全局配置
// 設(shè)置默認(rèn)參數(shù) $.ajaxSetup({ timeout: 3000, headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); // 使用 Promise $.getJSON('https://api.example.com/items') .done(data => console.log(data)) .fail((jqXHR, textStatus, errorThrown) => { console.error(textStatus, errorThrown); });
適用場(chǎng)景:
- 老項(xiàng)目維護(hù)
- 需要兼容 IE9 等舊瀏覽器
五、WebSocket(實(shí)時(shí)通信)
5.1 基礎(chǔ)實(shí)現(xiàn)
const socket = new WebSocket('wss://api.example.com/ws'); socket.onopen = function() { console.log('連接已建立'); socket.send(JSON.stringify({ action: 'subscribe', channel: 'updates' })); }; socket.onmessage = function(event) { const data = JSON.parse(event.data); console.log('收到消息:', data); }; socket.onclose = function(event) { console.log('連接關(guān)閉:', event.code, event.reason); };
5.2 斷線重連
let socket; function connect() { socket = new WebSocket(url); socket.onclose = function() { setTimeout(connect, 5000); }; } connect();
最佳實(shí)踐:
- 使用心跳包保持連接
- 實(shí)現(xiàn)消息隊(duì)列重發(fā)機(jī)制
- 使用 STOMP 等協(xié)議封裝
六、GraphQL 請(qǐng)求
6.1 使用 Fetch 實(shí)現(xiàn)
fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: ` query GetUser($id: ID!) { user(id: $id) { name email } } `, variables: { id: '123' } }) }) .then(res => res.json()) .then(data => console.log(data.data.user));
6.2 使用 Apollo Client
import { ApolloClient, InMemoryCache, gql } from '@apollo/client'; const client = new ApolloClient({ uri: '/graphql', cache: new InMemoryCache() }); client.query({ query: gql` query GetBooks { books { title author } } ` }).then(result => console.log(result.data));
七、綜合對(duì)比與選型指南
方案 | 適用場(chǎng)景 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|---|---|---|
XMLHttpRequest | 需要精細(xì)控制的老舊項(xiàng)目 | 無需額外依賴 | 代碼冗長(zhǎng),回調(diào)地獄 |
Fetch API | 現(xiàn)代瀏覽器項(xiàng)目 | 原生支持,簡(jiǎn)潔語法 | 需手動(dòng)處理錯(cuò)誤和超時(shí) |
Axios | 復(fù)雜企業(yè)級(jí)應(yīng)用 | 功能全面,攔截器機(jī)制 | 增加包體積 |
jQuery Ajax | 維護(hù)舊 jQuery 項(xiàng)目 | 簡(jiǎn)化異步操作 | 依賴 jQuery,已過時(shí) |
WebSocket | 實(shí)時(shí)通信需求 | 雙向?qū)崟r(shí)通信 | 實(shí)現(xiàn)復(fù)雜度高 |
GraphQL | 復(fù)雜數(shù)據(jù)查詢場(chǎng)景 | 精確獲取數(shù)據(jù),減少請(qǐng)求次數(shù) | 學(xué)習(xí)曲線陡峭 |
八、最佳實(shí)踐與安全防護(hù)
8.1 通用安全策略
// CSRF 防護(hù) axios.defaults.xsrfCookieName = 'csrftoken'; axios.defaults.xsrfHeaderName = 'X-CSRFToken'; // 請(qǐng)求簽名 function signRequest(config) { const timestamp = Date.now(); const signature = crypto.createHmac('sha256', SECRET) .update(`${config.url}${timestamp}`) .digest('hex'); config.headers['X-Signature'] = signature; config.headers['X-Timestamp'] = timestamp; return config; }
8.2 性能優(yōu)化方案
// 請(qǐng)求緩存 const cache = new Map(); async function cachedFetch(url) { if (cache.has(url)) { return cache.get(url); } const response = await fetch(url); const data = await response.json(); cache.set(url, data); return data; } // 請(qǐng)求合并 let pendingRequests = {}; function batchRequest(url) { if (!pendingRequests[url]) { pendingRequests[url] = fetch(url).then(res => res.json()); } return pendingRequests[url]; }
九、錯(cuò)誤處理標(biāo)準(zhǔn)范式
9.1 統(tǒng)一錯(cuò)誤處理
// Axios 錯(cuò)誤分類 function handleError(error) { if (error.response) { // 服務(wù)器響應(yīng)異常 (2xx 外的狀態(tài)碼) console.error('Server Error:', error.response.status); } else if (error.request) { // 請(qǐng)求已發(fā)出但無響應(yīng) console.error('Network Error:', error.message); } else { // 請(qǐng)求配置錯(cuò)誤 console.error('Config Error:', error.message); } }
9.2 重試機(jī)制實(shí)現(xiàn)
function fetchWithRetry(url, retries = 3) { return new Promise((resolve, reject) => { const attempt = (remaining) => { fetch(url) .then(resolve) .catch(error => { if (remaining > 0) { console.log(`剩余重試次數(shù): ${remaining}`); attempt(remaining - 1); } else { reject(error); } }); }; attempt(retries); }); }
十、TypeScript 類型增強(qiáng)
10.1 Axios 響應(yīng)類型
interface ApiResponse<T> { code: number; data: T; message: string; } const api = axios.create({ baseURL: '/api', responseType: 'json' }); api.interceptors.response.use( (response): ApiResponse<unknown> => { if (response.data.code !== 200) { throw new Error(response.data.message); } return response.data; } ); // 使用泛型請(qǐng)求 function getUser<T>(id: string) { return api.get<ApiResponse<T>>(`/users/${id}`); }
總結(jié)與擴(kuò)展方向
擴(kuò)展學(xué)習(xí)建議:
- 掌握 HTTP/2 服務(wù)器推送技術(shù)
- 研究 WebTransport 新協(xié)議
- 學(xué)習(xí) Service Worker 離線緩存
- 探索 WebRTC 點(diǎn)對(duì)點(diǎn)通信
版本兼容方案:
// 動(dòng)態(tài)加載 polyfill if (!window.fetch) { import('whatwg-fetch').then(() => { console.log('Fetch polyfill loaded'); }); }
根據(jù)項(xiàng)目需求靈活選擇請(qǐng)求方案,現(xiàn)代項(xiàng)目推薦優(yōu)先使用 Fetch API 或 Axios。始終遵循安全最佳實(shí)踐,在性能與功能需求間尋找平衡點(diǎn)。
到此這篇關(guān)于前端JavaScript 6 種主流接口請(qǐng)求技術(shù)的文章就介紹到這了,更多相關(guān)JS接口請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript 密碼框防止用戶粘貼和復(fù)制的實(shí)現(xiàn)代碼
本篇文章主要是對(duì)javascript 密碼框防止用戶粘貼和復(fù)制的實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-02-02js實(shí)現(xiàn)點(diǎn)贊按鈕功能的實(shí)例代碼
這篇文章主要介紹了js實(shí)現(xiàn)點(diǎn)贊按鈕功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的工作或?qū)W習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03JavaScript實(shí)現(xiàn)Tab點(diǎn)擊切換
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)Tab點(diǎn)擊切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07JS實(shí)現(xiàn)快速的導(dǎo)航下拉菜單動(dòng)畫效果附源碼下載
本文給大家分享一個(gè)帶有變形動(dòng)畫特效的下拉導(dǎo)航菜單特效,該導(dǎo)航菜單在菜單項(xiàng)之間切換時(shí),下拉菜單會(huì)快速的根據(jù)菜單內(nèi)容的大小來動(dòng)態(tài)變形,顯示合適的下拉菜單大小,效果非常棒。對(duì)導(dǎo)航下拉菜單代碼感興趣的朋友可以參考下本文2016-11-11

兼容FireFox 用javascript寫的一個(gè)畫圖函數(shù)

JavaScript之iterable_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

js獲取系統(tǒng)的根路徑實(shí)現(xiàn)介紹