柚子快報(bào)激活碼778899分享:vue.js Axios
柚子快報(bào)激活碼778899分享:vue.js Axios
一文了解Axios
1. Axios的引言
# axios的引言
Axios 是一個(gè) 異步請(qǐng)求 技術(shù)
# 異步請(qǐng)求
基于XMLHttpRequest對(duì)象發(fā)起的請(qǐng)求都是異步請(qǐng)求
# 異步請(qǐng)求特點(diǎn)
請(qǐng)求之后頁(yè)面不動(dòng),響應(yīng)回來更新的是頁(yè)面的局部,多個(gè)請(qǐng)求之間互不影響,并行執(zhí)行
ajax確實(shí)用來發(fā)送異步請(qǐng)求,ajax過氣
系統(tǒng)架構(gòu) 前后端分離架構(gòu)系統(tǒng) ---- 異步請(qǐng)求技術(shù) -----> Vue 全家桶系列 前端技術(shù)端 Vue 淘汰了jQuery
2. Axios基本入門
2.1 下載Axios
下載地址: https://unpkg.com/axios/dist/axios.min.js
2.2 Axios的案例
2.2.1 GET方式請(qǐng)求
2.2.2 POST方式的請(qǐng)求
# 總結(jié)
1. axios在發(fā)送post方式的請(qǐng)求時(shí)傳遞的參數(shù)如果為對(duì)象類型,axios會(huì)自動(dòng)將對(duì)象轉(zhuǎn)為json格式的字符串使用 application/json的請(qǐng)求頭向后端服務(wù)接口傳遞參數(shù)
2. axios的post請(qǐng)求傳遞參數(shù)的兩種方式:
第一種使用字符串進(jìn)行參數(shù)傳遞: "name=zhangsan&age=23" 這種形式
第二種方式后端接口直接使用@RequestBody注解形式接收參數(shù):
3. Axios的并發(fā)請(qǐng)求
并發(fā)請(qǐng)求: 在同一時(shí)間發(fā)送多個(gè)不同的請(qǐng)求到后端服務(wù),最后同一處理不同服務(wù)的響應(yīng)結(jié)果
# 總結(jié)
1.針對(duì)于并發(fā)請(qǐng)求需要用到axios.all()函數(shù)來完成并發(fā)請(qǐng)求的處理
2.針對(duì)于并發(fā)請(qǐng)求的結(jié)果匯總需要使用axios.spread()函數(shù)來統(tǒng)一匯總請(qǐng)求結(jié)果
4. Axios的Restful風(fēng)格的API
# Axios的API總結(jié)
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
NOTE:
在使用別名方法時(shí), url、method、data 這些屬性都不必在配置中指定。
.get(url[, config])、.post(url[, data[, config]])這樣的別名方法時(shí),參數(shù)的含義略有不同:
url: 目標(biāo)地址。data: (對(duì)于.post(), .put(), .patch()等)指請(qǐng)求體的數(shù)據(jù)。config: (可選)額外的配置項(xiàng),覆蓋或補(bǔ)充默認(rèn)配置。在別名方法中,你不必顯式指定method,因?yàn)榉椒呀?jīng)確定了HTTP方法類型。包括:
url: 必需。一個(gè)字符串,表示請(qǐng)求的目標(biāo)地址(URL)。method: 可選。一個(gè)字符串,表示HTTP請(qǐng)求方法,如GET, POST, PUT, DELETE等。如果使用.get(), .post()等別名方法,則此屬性不需要手動(dòng)指定,因?yàn)樗煞椒Q隱含。data: 可選。請(qǐng)求體的數(shù)據(jù)。在POST, PUT, 和PATCH請(qǐng)求中通常用于發(fā)送數(shù)據(jù)到服務(wù)器??梢允菍?duì)象、數(shù)組、字符串等,具體格式取決于Content-Type。headers: 可選。一個(gè)對(duì)象,包含請(qǐng)求頭信息。例如,可以設(shè)置{'Content-Type': 'application/json'}來指定發(fā)送JSON格式的數(shù)據(jù)。params: 可選。一個(gè)對(duì)象或URLSearchParams對(duì)象,包含URL查詢字符串的鍵值對(duì)。這對(duì)于GET請(qǐng)求特別有用,用于傳遞查詢參數(shù)。timeout: 可選。設(shè)置請(qǐng)求超時(shí)時(shí)間(毫秒)。如果請(qǐng)求時(shí)間超過這個(gè)值,請(qǐng)求會(huì)被中斷并拋出錯(cuò)誤。
注意:config對(duì)象可以包含url屬性來指定請(qǐng)求的URL,但是單獨(dú)提供url參數(shù)的目的是為了簡(jiǎn)化調(diào)用和提高代碼的可讀性
5.Axios的高級(jí)使用配置對(duì)象
1.全局 axios 默認(rèn)值:像家里的默認(rèn)規(guī)則
想象一下,你家里有一些默認(rèn)的生活規(guī)則,比如晚上10點(diǎn)以后要保持安靜。在Axios中,全局默認(rèn)配置就像是這些家規(guī),它們會(huì)影響到所有的網(wǎng)絡(luò)請(qǐng)求。
// 設(shè)置一個(gè)大家都要遵守的基地地址
axios.defaults.baseURL = 'https://api.example.com';
// 給所有請(qǐng)求加一個(gè)通行令牌,就像出門都需要帶的鑰匙
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// 對(duì)于發(fā)送POST請(qǐng)求,我們統(tǒng)一規(guī)定用什么樣的包裝紙(Content-Type)
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
2.自定義實(shí)例默認(rèn)值:特定房間的特別規(guī)則
現(xiàn)在,假設(shè)你家里有一個(gè)書房,里面有些特別的規(guī)矩,比如必須穿拖鞋進(jìn)入。在Axios中,你可以創(chuàng)建一個(gè)自定義的實(shí)例,它有自己的默認(rèn)配置,就像書房的特別規(guī)則。
// 創(chuàng)建實(shí)例時(shí)配置默認(rèn)值
const instance = axios.create({
baseURL: 'https://api.example.com'
});
// 創(chuàng)建實(shí)例后修改默認(rèn)值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// 創(chuàng)建一個(gè)新助手(實(shí)例),并告訴他我們的基地地址
const 我的專屬助手 = axios.create({
baseURL: 'https://api.mycoolproject.com'
});
// 給這個(gè)助手也配一把特別的鑰匙
我的專屬助手.defaults.headers.common['Authorization'] = '我的書房鑰匙';
// 即使后來發(fā)現(xiàn)需要調(diào)整規(guī)則,比如換一種包裝紙,也很容易
我的專屬助手.defaults.headers.post['Content-Type'] = 'application/json';
3.配置的優(yōu)先級(jí)
想象你正在組織一次野餐活動(dòng),關(guān)于野餐的具體安排(比如地點(diǎn)、時(shí)間),會(huì)有幾個(gè)來源的規(guī)定:
社區(qū)規(guī)定:社區(qū)有一套默認(rèn)的野餐規(guī)則,比如通常都在公園舉行,下午兩點(diǎn)開始。小組規(guī)定:你的小組可能會(huì)根據(jù)成員的需要調(diào)整這些規(guī)則,比如改為早上十點(diǎn)在湖邊開始。個(gè)人需求:最后,每個(gè)參與者的個(gè)別需求也會(huì)被考慮,比如某人那天只能晚到,所以他的野餐時(shí)間會(huì)單獨(dú)調(diào)整到下午三點(diǎn)。
在Axios中,配置的設(shè)定也是類似的分層概念,從最通用到最具體:
庫(kù)的默認(rèn)配置:就像社區(qū)規(guī)定,是最基本的設(shè)定,適用于所有人但可被覆蓋。實(shí)例的默認(rèn)配置:類似于小組規(guī)定,針對(duì)特定的一組請(qǐng)求做了定制,覆蓋了庫(kù)的默認(rèn)設(shè)置。單次請(qǐng)求的配置:這相當(dāng)于個(gè)人需求,是最具體的,只對(duì)某一次請(qǐng)求有效,會(huì)覆蓋前兩層的所有設(shè)定。
// 使用庫(kù)提供的默認(rèn)配置創(chuàng)建實(shí)例
// 此時(shí)超時(shí)配置的默認(rèn)值是 `0`
const instance = axios.create();
// 重寫庫(kù)的超時(shí)默認(rèn)值
// 現(xiàn)在,所有使用此實(shí)例的請(qǐng)求都將等待2.5秒,然后才會(huì)超時(shí)
instance.defaults.timeout = 2500;
// 重寫此請(qǐng)求的超時(shí)時(shí)間,因?yàn)樵撜?qǐng)求需要很長(zhǎng)時(shí)間
instance.get('/longRequest', {
timeout: 5000
});
庫(kù)的默認(rèn)值:Axios小助手自帶了一套默認(rèn)工作方式,比如默認(rèn)情況下,它可能不會(huì)等待太久就認(rèn)為請(qǐng)求失敗了(超時(shí)時(shí)間默認(rèn)是0,表示沒有特別設(shè)定)。實(shí)例的配置:你可以定制一個(gè)特殊的Axios小助手實(shí)例,專門用來處理那些可能需要更長(zhǎng)時(shí)間的任務(wù)。比如,你設(shè)置了這個(gè)實(shí)例的超時(shí)時(shí)間為2.5秒(instance.defaults.timeout = 2500;),這意味著使用這個(gè)實(shí)例發(fā)起的請(qǐng)求會(huì)比一般的請(qǐng)求更有耐心,愿意多等等看。單次請(qǐng)求的特殊要求:有時(shí)候,即便是這個(gè)特殊實(shí)例的耐心也不夠,比如有個(gè)請(qǐng)求(去很遠(yuǎn)的地方拿特別的食材)明確知道會(huì)花更長(zhǎng)時(shí)間。這時(shí),你可以在發(fā)起這個(gè)特定請(qǐng)求時(shí)單獨(dú)指定更長(zhǎng)的等待時(shí)間(timeout: 5000),也就是說,這一次請(qǐng)求會(huì)等待5秒鐘才認(rèn)為超時(shí)。
4. 配置對(duì)象
{
// `url` 是用于請(qǐng)求的服務(wù)器 URL
url: '/user',
// `method` 是創(chuàng)建請(qǐng)求時(shí)使用的方法
method: 'get', // 默認(rèn)是 get
// `baseURL` 將自動(dòng)加在 `url` 前面,除非 `url` 是一個(gè)絕對(duì) URL。
// 它可以通過設(shè)置一個(gè) `baseURL` 便于為 axios 實(shí)例的方法傳遞相對(duì) URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允許在向服務(wù)器發(fā)送前,修改請(qǐng)求數(shù)據(jù)
// 只能用在 'PUT', 'POST' 和 'PATCH' 這幾個(gè)請(qǐng)求方法
// 后面數(shù)組中的函數(shù)必須返回一個(gè)字符串,或 ArrayBuffer,或 Stream
transformRequest: [function (data) {
// 對(duì) data 進(jìn)行任意轉(zhuǎn)換處理
return data;
}],
// `transformResponse` 在傳遞給 then/catch 前,允許修改響應(yīng)數(shù)據(jù)
transformResponse: [function (data) {
// 對(duì) data 進(jìn)行任意轉(zhuǎn)換處理
return data;
}],
// `headers` 是即將被發(fā)送的自定義請(qǐng)求頭
headers: {'X-Requested-With': 'XMLHttpRequest'},
// `params` 是即將與請(qǐng)求一起發(fā)送的 URL 參數(shù)
// 必須是一個(gè)無格式對(duì)象(plain object)或 URLSearchParams 對(duì)象
params: {
ID: 12345
},
// `paramsSerializer` 是一個(gè)負(fù)責(zé) `params` 序列化的函數(shù)
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
// `data` 是作為請(qǐng)求主體被發(fā)送的數(shù)據(jù)
// 只適用于這些請(qǐng)求方法 'PUT', 'POST', 和 'PATCH'
// 在沒有設(shè)置 `transformRequest` 時(shí),必須是以下類型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 瀏覽器專屬:FormData, File, Blob
// - Node 專屬: Stream
data: {
firstName: 'Fred'
},
// `timeout` 指定請(qǐng)求超時(shí)的毫秒數(shù)(0 表示無超時(shí)時(shí)間)
// 如果請(qǐng)求話費(fèi)了超過 `timeout` 的時(shí)間,請(qǐng)求將被中斷
timeout: 1000,
// `withCredentials` 表示跨域請(qǐng)求時(shí)是否需要使用憑證
withCredentials: false, // 默認(rèn)的
// `adapter` 允許自定義處理請(qǐng)求,以使測(cè)試更輕松
// 返回一個(gè) promise 并應(yīng)用一個(gè)有效的響應(yīng) (查閱 [response docs](#response-api)).
adapter: function (config) {
/* ... */
},
// `auth` 表示應(yīng)該使用 HTTP 基礎(chǔ)驗(yàn)證,并提供憑據(jù)
// 這將設(shè)置一個(gè) `Authorization` 頭,覆寫掉現(xiàn)有的任意使用 `headers` 設(shè)置的自定義 `Authorization`頭
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// `responseType` 表示服務(wù)器響應(yīng)的數(shù)據(jù)類型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // 默認(rèn)的
// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名稱
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` 是承載 xsrf token 的值的 HTTP 頭的名稱
xsrfHeaderName: 'X-XSRF-TOKEN', // 默認(rèn)的
// `onUploadProgress` 允許為上傳處理進(jìn)度事件
onUploadProgress: function (progressEvent) {
// 對(duì)原生進(jìn)度事件的處理
},
// `onDownloadProgress` 允許為下載處理進(jìn)度事件
onDownloadProgress: function (progressEvent) {
// 對(duì)原生進(jìn)度事件的處理
},
// `maxContentLength` 定義允許的響應(yīng)內(nèi)容的最大尺寸
maxContentLength: 2000,
// `validateStatus` 定義對(duì)于給定的HTTP 響應(yīng)狀態(tài)碼是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者設(shè)置為 `null` 或 `undefined`),promise 將被 resolve; 否則,promise 將被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // 默認(rèn)的
},
// `maxRedirects` 定義在 node.js 中 follow 的最大重定向數(shù)目
// 如果設(shè)置為0,將不會(huì) follow 任何重定向
maxRedirects: 5, // 默認(rèn)的
// `httpAgent` 和 `httpsAgent` 分別在 node.js 中用于定義在執(zhí)行 http 和 https 時(shí)使用的自定義代理。允許像這樣配置選項(xiàng):
// `keepAlive` 默認(rèn)沒有啟用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// 'proxy' 定義代理服務(wù)器的主機(jī)名稱和端口
// `auth` 表示 HTTP 基礎(chǔ)驗(yàn)證應(yīng)當(dāng)用于連接代理,并提供憑據(jù)
// 這將會(huì)設(shè)置一個(gè) `Proxy-Authorization` 頭,覆寫掉已有的通過使用 `header` 設(shè)置的自定義 `Proxy-Authorization` 頭。
proxy: {
host: '127.0.0.1',
port: 9000,
auth: : {
username: 'mikeymike',
password: 'rapunz3l'
}
},
// `cancelToken` 指定用于取消請(qǐng)求的 cancel token
// (查看后面的 Cancellation 這節(jié)了解更多)
cancelToken: new CancelToken(function (cancel) {
})
}
5.使用配置對(duì)象形式發(fā)送請(qǐng)求
var instance = axios.create({
method:"GET",
baseURL:"http://localhost:8888",
data:{ //作為請(qǐng)求體發(fā)送的數(shù)據(jù),只適用于這些請(qǐng)求方法 'PUT', 'POST', 和 'PATCH'
}
});
instance.get("/axios/findAll?username=zhangsan");
當(dāng)然可以,讓我們用更簡(jiǎn)單易懂的方式解釋Axios中的錯(cuò)誤處理機(jī)制,并結(jié)合代碼示例。
6.錯(cuò)誤處理
想象一下,你派了個(gè)小信使(axios)去城堡(服務(wù)器)取信(數(shù)據(jù))。路上可能會(huì)發(fā)生各種情況,比如城堡拒絕給信、信使迷路了或者信使根本沒出發(fā)。我們就要為這些情況做好準(zhǔn)備。
1.基本錯(cuò)誤捕獲
axios.get('/user/12345') // 嘗試去獲取編號(hào)12345的用戶信息
.catch(function (error) { // 如果路上出了問題,就執(zhí)行這里的代碼
// 分三種情況討論:
// 1. 城堡回復(fù)了,但說“不行”(狀態(tài)碼不是200系列)
if (error.response) {
console.log("城堡的回復(fù)是:", error.response.data);
console.log("回復(fù)的詳細(xì)狀態(tài):", error.response.status);
console.log("回復(fù)里還有什么:", error.response.headers);
}
// 2. 信使出發(fā)了,但沒收到城堡任何回復(fù)(可能是網(wǎng)絡(luò)斷了)
else if (error.request) {
console.log("信使出發(fā)了,但沒帶回任何城堡的消息", error.request);
}
// 3. 信使根本就沒出發(fā)(配置錯(cuò)誤之類的)
else {
console.log("哎呀,信使都沒出發(fā)呢!", error.message);
}
// 總之,打印出這次任務(wù)的完整配置,方便查找問題
console.log("任務(wù)的原始計(jì)劃是這樣的:", error.config);
});
2.自定義錯(cuò)誤判斷:validateStatus
有時(shí)候,你可能覺得城堡回復(fù)“400”之類的也不算大問題,還想繼續(xù)處理。這就用到validateStatus了。
axios.get('/user/12345', {
validateStatus: function (status) { // 自定義規(guī)則:只要狀態(tài)碼不到500,就算成功
return status < 500;
}
})
3.獲取錯(cuò)誤詳情:toJSON
如果想深入了解錯(cuò)誤的全貌,可以用toJSON方法。
axios.get('/user/12345')
.catch(function (error) {
console.log("錯(cuò)誤的全部細(xì)節(jié):", error.toJSON());
});
總結(jié):錯(cuò)誤處理就是為你的網(wǎng)絡(luò)請(qǐng)求之旅準(zhǔn)備應(yīng)對(duì)各種意外的方案。無論是城堡拒絕(狀態(tài)碼異常)、信使迷路(請(qǐng)求發(fā)出但無響應(yīng)),還是信使壓根沒出發(fā)(請(qǐng)求配置出錯(cuò)),我們都要有所準(zhǔn)備,確保即使遇到問題也能妥善處理。通過自定義錯(cuò)誤判斷和獲取詳細(xì)錯(cuò)誤信息,我們可以更靈活、細(xì)致地處理這些情況。
7.攔截器
當(dāng)然可以,讓我們用更簡(jiǎn)單直白的語言來解釋一下Axios中的攔截器是什么以及如何使用它們。
1.什么是攔截器?
想象一下,你寄了一個(gè)信(請(qǐng)求)或者收到了一個(gè)包裹(響應(yīng)),攔截器就像是你家門前的信箱保安。它可以在你的信件出去之前檢查一遍,也可以在收到包裹之后先打開看看。在 Axios 中,攔截器就是這樣的“保安”,它允許你在請(qǐng)求發(fā)送到服務(wù)器前或從服務(wù)器接收到響應(yīng)后執(zhí)行一些操作。
2.請(qǐng)求攔截器
用途: 在請(qǐng)求真正飛往服務(wù)器之前,你可以用它來做一些事情,比如自動(dòng)給每個(gè)請(qǐng)求加上身份驗(yàn)證信息、處理請(qǐng)求參數(shù)等。
axios.interceptors.request.use(function (config) {
// 這里是在請(qǐng)求發(fā)送前做的事情
console.log('請(qǐng)求即將發(fā)出,我來檢查一下...');
// 比如,添加一個(gè)token到請(qǐng)求頭中
if(localStorage.token) {
config.headers.Authorization = `Bearer ${localStorage.token}`;
}
// 最后記得返回修改后的配置信息
return config;
}, function (error) {
// 如果請(qǐng)求準(zhǔn)備過程中出錯(cuò)了,這里可以捕獲錯(cuò)誤并處理
console.error('哎呀,請(qǐng)求還沒發(fā)就出錯(cuò)了:', error);
// 記得把錯(cuò)誤繼續(xù)拋出,不然請(qǐng)求就被你攔下了
return Promise.reject(error);
});
擴(kuò)充(小白看過來):
Promise.reject(error) 的含義:
在JavaScript中,Promise是一種處理異步操作的方法,它有兩種結(jié)果:成功(resolved)和失?。╮ejected)。當(dāng)我們用.then處理成功的情況,用.catch處理失敗的情況。
Promise.reject(error)的作用是創(chuàng)建一個(gè)已經(jīng)被標(biāo)記為失?。╮ejected)的Promise對(duì)象,并且這個(gè)失敗的原因是error。換句話說,就是在告訴接下來的.catch處理程序:“嘿,出錯(cuò)了,錯(cuò)誤信息在這里?!?/p>
在攔截器中使用它,是為了保證錯(cuò)誤能夠被正確的傳遞和處理。如果不使用Promise.reject(error),錯(cuò)誤就會(huì)被攔截器吞掉,外部調(diào)用者就不知道請(qǐng)求或響應(yīng)處理過程中出現(xiàn)了問題。
例子簡(jiǎn)化說明
請(qǐng)求攔截器里用了Promise.reject(error),是因?yàn)槿绻跍?zhǔn)備請(qǐng)求時(shí)出錯(cuò)(比如配置錯(cuò)誤),你需要把這個(gè)錯(cuò)誤告知調(diào)用者,讓他們能在.catch中處理這個(gè)錯(cuò)誤。響應(yīng)攔截器中同樣使用,意味著如果對(duì)響應(yīng)的處理出了問題(比如期望的格式不符),也要通過拋出這個(gè)錯(cuò)誤,確保外部調(diào)用者能夠感知并處理。
3.響應(yīng)攔截器
用途: 當(dāng)服務(wù)器的響應(yīng)回來時(shí),攔截器可以先一步接收,這樣你就可以在數(shù)據(jù)到達(dá)應(yīng)用的其他部分之前進(jìn)行處理,比如解析數(shù)據(jù)、統(tǒng)一處理錯(cuò)誤信息等。
axios.interceptors.response.use(function (response) {
// 響應(yīng)成功到達(dá),這里可以先看看
console.log('收到響應(yīng)了,讓我先瞧瞧...');
// 可以直接返回?cái)?shù)據(jù)部分,讓使用更方便
return response.data;
}, function (error) {
// 如果服務(wù)器返回了錯(cuò)誤狀態(tài)碼,這里可以捕獲并統(tǒng)一處理
console.error('服務(wù)器好像不太高興,給了我一個(gè)錯(cuò)誤:', error.response.status);
// 根據(jù)錯(cuò)誤類型,你可以自定義錯(cuò)誤處理邏輯,比如提示用戶
if(error.response.status === 401) {
alert('登錄過期了,請(qǐng)重新登錄!');
}
// 別忘了返回錯(cuò)誤,以便調(diào)用處能知道并處理
return Promise.reject(error);
});
4.移除攔截器
如果某個(gè)時(shí)候你不再需要某個(gè)攔截器了,可以這樣移除它:
// 先保存攔截器的引用
const myRequestInterceptor = axios.interceptors.request.use(/*...*/);
// 等到需要的時(shí)候
axios.interceptors.request.eject(myRequestInterceptor);
5.給自定義實(shí)例添加攔截器
如果你創(chuàng)建了自己的Axios實(shí)例,也可以為這個(gè)特定的實(shí)例單獨(dú)設(shè)置攔截器,這樣不會(huì)影響到全局的Axios配置。
const myInstance = axios.create();
// 為這個(gè)實(shí)例添加請(qǐng)求攔截器
myInstance.interceptors.request.use(function (config) {
// 特定于這個(gè)實(shí)例的處理邏輯
return config;
});
// 使用這個(gè)實(shí)例發(fā)送請(qǐng)求,將使用上面定義的攔截器
myInstance.get('/some-url');
8.取消請(qǐng)求
1.取消請(qǐng)求就像掛斷電話一樣簡(jiǎn)單
想象一下,你正在用手機(jī)打電話查詢電影票,但突然決定不看了。這時(shí),你就會(huì)掛斷電話,停止與電影院的通話。在互聯(lián)網(wǎng)世界里,當(dāng)你向網(wǎng)站發(fā)送請(qǐng)求獲取數(shù)據(jù)時(shí),有時(shí)候你也可能需要“掛斷”這個(gè)請(qǐng)求,這就是“取消請(qǐng)求”。
Axios,一個(gè)常用的網(wǎng)絡(luò)請(qǐng)求庫(kù),提供了兩種方式讓你能優(yōu)雅地“掛斷”請(qǐng)求:AbortController 和 CancelToken。不過要注意,從Axios的一個(gè)較新版本開始,推薦使用AbortController,而CancelToken已經(jīng)過時(shí)了。
2.使用AbortController(推薦)
想象AbortController是一個(gè)遙控器,可以隨時(shí)停止你的請(qǐng)求任務(wù)。
準(zhǔn)備遙控器:const controller = new AbortController();
發(fā)起請(qǐng)求,并給它配上遙控器:axios.get('/get-movie-times', {
signal: controller.signal // 這就是告訴請(qǐng)求,用哪個(gè)遙控器控制
}).then(...).catch(...);
想取消請(qǐng)求時(shí),按下遙控器的按鈕:controller.abort(); // 請(qǐng)求就被取消了
3.使用CancelToken(已過時(shí),盡量別用)
盡管不推薦新項(xiàng)目使用,但了解一下也無妨。想象CancelToken是一張可以撕毀的門票,一旦撕了,就進(jìn)不了電影院了。
制作可撕毀的門票:const CancelToken = axios.CancelToken;
const source = CancelToken.source(); // 這個(gè)source就像是門票和撕票機(jī)的組合
買票(發(fā)起請(qǐng)求),并帶上可撕的門票:axios.get('/buy-ticket', {
cancelToken: source.token
}).then(...).catch(...);
不想看電影了?撕掉門票?。簊ource.cancel('改變主意,不看電影了。');
小貼士:
你可以用同一個(gè)遙控器(AbortController)或門票(CancelToken)控制多個(gè)請(qǐng)求。如果你同時(shí)知道這兩種方法,也沒問題,在過渡階段兩者可以混用,但記得優(yōu)先考慮新的、更現(xiàn)代的方法——AbortController。
簡(jiǎn)單來說,就是準(zhǔn)備一個(gè)控制工具,然后在請(qǐng)求時(shí)告訴它,如果需要,就用這個(gè)工具來停止請(qǐng)求。
9.axios的二次封裝
當(dāng)然可以,讓我們一起來探討如何對(duì)Axios進(jìn)行二次封裝,這個(gè)過程不僅適合編程新手理解,也能為經(jīng)驗(yàn)豐富的開發(fā)者提供一些實(shí)用的見解。Axios 是一個(gè)基于 promise 的 HTTP 庫(kù),它在前端開發(fā)中被廣泛用于發(fā)送 AJAX 請(qǐng)求。二次封裝的目的是為了提高代碼的可維護(hù)性、可讀性和靈活性,比如統(tǒng)一處理錯(cuò)誤、添加請(qǐng)求攔截器、響應(yīng)攔截器等。
1.為什么需要封裝 Axios
統(tǒng)一錯(cuò)誤處理:避免在每個(gè)請(qǐng)求中重復(fù)編寫錯(cuò)誤處理邏輯。請(qǐng)求攔截與響應(yīng)攔截:在請(qǐng)求發(fā)送前和響應(yīng)接收后執(zhí)行某些操作,如自動(dòng)添加 Token、處理返回狀態(tài)碼等。配置默認(rèn)值:如設(shè)置默認(rèn)的基礎(chǔ)URL、超時(shí)時(shí)間等。簡(jiǎn)化API調(diào)用:通過自定義方法讓API調(diào)用更簡(jiǎn)潔明了。
2.準(zhǔn)備工作
確保你的項(xiàng)目中已經(jīng)安裝了Axios庫(kù)。如果沒有安裝,可以通過npm或yarn來安裝:
npm install axios
# 或者
yarn add axios
3.開始封裝
1. 創(chuàng)建封裝文件
首先,在你的項(xiàng)目中創(chuàng)建一個(gè)名為http.js(或你偏好的命名)的文件,這將是我們的封裝起點(diǎn)。
2. 基礎(chǔ)封裝
在http.js中,我們首先引入Axios,并定義基本的配置項(xiàng)。
import axios from 'axios';
// 設(shè)置基礎(chǔ)URL和超時(shí)時(shí)間
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // 根據(jù)環(huán)境變量獲取基礎(chǔ)URL
timeout: 5000, // 請(qǐng)求超時(shí)時(shí)間
});
export default service;
3. 錯(cuò)誤處理
接下來,我們來實(shí)現(xiàn)錯(cuò)誤的統(tǒng)一處理。這包括網(wǎng)絡(luò)錯(cuò)誤、服務(wù)器錯(cuò)誤等。
service.interceptors.response.use(
response => {
// 對(duì)響應(yīng)數(shù)據(jù)做處理,這里可以根據(jù)實(shí)際需求定制
return response.data;
},
error => {
console.error('請(qǐng)求出錯(cuò):', error);
if (error.response) {
// 請(qǐng)求已發(fā)出,但服務(wù)器響應(yīng)的狀態(tài)碼不在 2xx 范圍內(nèi)
const { status, data } = error.response;
// 根據(jù)不同的錯(cuò)誤碼做相應(yīng)處理
switch (status) {
case 401:
// 處理未授權(quán)的情況
break;
case 403:
// 處理無權(quán)限的情況
break;
case 404:
// 處理資源不存在的情況
break;
default:
// 其他錯(cuò)誤處理
break;
}
} else if (error.request) {
// 請(qǐng)求發(fā)出了,但沒有收到響應(yīng)
console.error('請(qǐng)求已發(fā)出,但沒有收到響應(yīng)');
} else {
// 發(fā)生了一些問題,導(dǎo)致請(qǐng)求未能發(fā)出
console.error('請(qǐng)求配置存在問題');
}
return Promise.reject(error);
}
);
4. 請(qǐng)求攔截器
在請(qǐng)求發(fā)送前,我們可能需要做一些預(yù)處理,如添加認(rèn)證信息。
service.interceptors.request.use(config => {
// 在發(fā)送請(qǐng)求之前做些什么,例如添加Token
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}, error => {
// 請(qǐng)求錯(cuò)誤處理
return Promise.reject(error);
});
5. 導(dǎo)出封裝好的服務(wù)
確保你的封裝結(jié)果能被其他模塊使用。
export default service;
6.如何使用封裝后的Axios
在你的應(yīng)用中,你可以像這樣使用封裝后的Axios實(shí)例:
import http from './http';
http.get('/api/data')
.then(response => {
console.log('成功獲取數(shù)據(jù):', response);
})
.catch(error => {
console.error('請(qǐng)求失敗:', error);
});
10.API模塊化
API模塊化:提升項(xiàng)目結(jié)構(gòu)的清晰度與可維護(hù)性
API模塊化是將應(yīng)用程序中的所有API請(qǐng)求按照功能或者業(yè)務(wù)模塊進(jìn)行分類組織的一種設(shè)計(jì)模式。這樣做不僅可以讓代碼結(jié)構(gòu)更加清晰,便于團(tuán)隊(duì)協(xié)作,還能顯著提升項(xiàng)目的可維護(hù)性和擴(kuò)展性。下面我們將詳細(xì)介紹如何進(jìn)行API模塊化,同時(shí)對(duì)比它與Axios基本封裝的區(qū)別。
1.為什么需要API模塊化
清晰的代碼結(jié)構(gòu):將API按模塊劃分,使得相關(guān)功能的代碼聚集在一起,易于查找和管理。便于團(tuán)隊(duì)協(xié)作:每個(gè)成員可以專注于自己負(fù)責(zé)的模塊,減少代碼沖突。易于維護(hù)和擴(kuò)展:隨著項(xiàng)目發(fā)展,新功能的加入或舊功能的調(diào)整更加靈活方便。重用和標(biāo)準(zhǔn)化:重復(fù)使用的API調(diào)用可以封裝成通用方法,減少代碼重復(fù),提高代碼質(zhì)量。
2.API模塊化的步驟
以Vue.js項(xiàng)目為例,假設(shè)我們正在開發(fā)一個(gè)包含用戶管理和文章管理的Web應(yīng)用。
創(chuàng)建API目錄
在項(xiàng)目的src目錄下創(chuàng)建一個(gè)名為api的文件夾,用于存放所有API模塊。
劃分模塊并創(chuàng)建文件
在api目錄下,根據(jù)業(yè)務(wù)模塊創(chuàng)建相應(yīng)的JS文件,如user.js和article.js。
src/
└── api/
├── user.js
└── article.js
編寫API模塊
以u(píng)ser.js為例,我們?cè)谶@里封裝與用戶相關(guān)的所有API請(qǐng)求。
// src/api/user.js
import http from '../http'; // 引入我們之前封裝的axios實(shí)例
export function login(data) {
return http.post('/user/login', data);
}
export function getUserInfo(userId) {
return http.get(`/user/${userId}`);
}
// ...其他用戶相關(guān)API
同理,在article.js中封裝文章相關(guān)的API。
注意:
, data后面跟著的data就是你要發(fā)送給服務(wù)器的數(shù)據(jù)。在這個(gè)例子中,data可能包含了用戶的登錄信息,比如用戶名和密碼。就像你準(zhǔn)備了一份禮物(數(shù)據(jù)),通過POST請(qǐng)求這個(gè)“快遞員”送到服務(wù)器指定的房間(/user/login)。
具體過程
準(zhǔn)備階段:你通過login({ username: 'test', password: 'test' })調(diào)用,創(chuàng)建了一個(gè)包含用戶名和密碼的對(duì)象。打包禮物:這個(gè)對(duì)象(禮物)被當(dāng)作data參數(shù),準(zhǔn)備通過POST請(qǐng)求發(fā)送。發(fā)起請(qǐng)求:http.post('/user/login', data)這行代碼就像發(fā)送指令,“請(qǐng)把這份包含用戶名和密碼的禮物送到/user/login這個(gè)房間?!狈?wù)器響應(yīng):服務(wù)器收到請(qǐng)求后,會(huì)處理這些數(shù)據(jù)(比如驗(yàn)證用戶名和密碼是否正確),然后返回一個(gè)響應(yīng),告訴客戶端(你的應(yīng)用)登錄是否成功。處理結(jié)果:在你的代碼中,通常會(huì)在.then()或.catch()中處理服務(wù)器的響應(yīng),也就是判斷登錄是否成功,并做出相應(yīng)的操作,比如跳轉(zhuǎn)頁(yè)面或顯示錯(cuò)誤信息。
在應(yīng)用中使用
現(xiàn)在,你可以在任何需要的地方直接導(dǎo)入并使用這些API。
import { login } from '@/api/user';
import { getArticleList } from '@/api/article';
login({ username: 'test', password: 'test' })
.then(response => {
console.log('登錄成功', response);
getArticleList()
.then(articleList => console.log('文章列表', articleList))
.catch(err => console.error('獲取文章列表失敗', err));
})
.catch(error => console.error('登錄失敗', error));
3.API模塊化與Axios封裝的區(qū)別
目標(biāo)不同:
Axios封裝主要關(guān)注于對(duì)HTTP請(qǐng)求的低層抽象,如全局錯(cuò)誤處理、請(qǐng)求/響應(yīng)攔截、默認(rèn)配置等,旨在簡(jiǎn)化單個(gè)請(qǐng)求的使用。API模塊化則是在Axios封裝的基礎(chǔ)上,進(jìn)一步對(duì)業(yè)務(wù)邏輯層面的請(qǐng)求進(jìn)行組織和管理,強(qiáng)調(diào)的是代碼結(jié)構(gòu)和團(tuán)隊(duì)協(xié)作的優(yōu)化。 層次不同:
Axios封裝屬于技術(shù)基礎(chǔ)設(shè)施層,是所有網(wǎng)絡(luò)請(qǐng)求的基礎(chǔ)。API模塊化則更偏向于業(yè)務(wù)邏輯層,它直接服務(wù)于特定的業(yè)務(wù)功能。 作用范圍不同:
Axios封裝影響整個(gè)項(xiàng)目的所有網(wǎng)絡(luò)請(qǐng)求行為。API模塊化則僅限于其所屬的業(yè)務(wù)模塊,有助于保持代碼的高內(nèi)聚、低耦合。
柚子快報(bào)激活碼778899分享:vue.js Axios
相關(guān)鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。