目錄
- 一、簡介
- 二、安裝與配置
- 三、axios用法
- 1.axios泛型參數
- (1).第三個泛型參數-約束data請求參數的類型
- (2).第二個泛型參數-決定后臺返回數據的類型
- 2.axios攔截器
- 3.請求工具封裝
- 統一處理業務狀態碼錯誤
- 統一處理401或404錯誤
一、簡介
Axios 是一個基于 Promise 的網絡請求庫,可以運行在 Node.js 和瀏覽器中。在鴻蒙生態中,它是基于 http 模塊封裝的優秀請求庫。
選擇 Axios 的原因:
- 多平臺實現:可用鴻蒙、前端、NodeJS 后端
- 質量穩定:ohos 官方推薦的第三方倉庫
- 支持攔截器:請求攔截器,響應攔截器(通用業務處理)
Axios 的核心能力包括:
- HTTP 請求
- Promise API
- request 和 response 攔截器
- 轉換 request 和 response 的 data 數據
- 自動轉換 JSON data 數據
接口與屬性列表
接口列表
接口 | 參數 | 功能 |
---|---|---|
axios(config) | config:請求配置 | 發送請求 |
axios.create(config) | config:請求配置 | 創建實例 |
axios.request(config) | config:請求配置 | 發送請求 |
axios.get(url[, config]) | url:請求地址config:請求配置 | 發送get請求 |
axios.delete(url[, config]) | url:請求地址config:請求配置 | 發送delete請求 |
axios.post(url[, data[, config]]) | url:請求地址 data:發送請求體數據 config:請求配置 | 發送post請求 |
axios.put(url[, data[, config]]) | url:請求地址 data:發送請求體數據 config:請求配置 | 發送put請求 |
屬性列表
屬性 | 描述 |
---|---|
axios.defaults[‘xxx’] | 默認設置 。值為請求配置 config 中的配置項 例如 axios.defaults.headers 獲取頭部信息 |
axios.interceptors | 攔截器 |
二、安裝與配置
下載安裝
需要權限
在src/main/module.json5中添加網絡權限
三、axios用法
1.axios泛型參數
(1).第三個泛型參數-約束data請求參數的類型
/** 賬號密碼登錄模型*/
export interface ApifoxModel1 {/*** 用戶密碼*/passwd?: string;/*** 用戶手機號*/phone?: string;
}
Button('泛型參數-約束post請求參數').onClick(async () => {// 第三個泛型參數:約束請求體(data)參數的類型 - 重點await axios.post<null, null, PostUserLoginPasswdData>('https://guardianapi.itheima.net/user/login/passwd',{phone: '120666666666',passwd: '888itcast.CN764%...'})promptAction.showToast({message: '登錄請求發送成功'})
})
(2).第二個泛型參數-決定后臺返回數據的類型
/*** 數據響應模型?登錄VO?*/
export interface ServiceResponse<R> {/*** 請求碼,200為成功,300及300以上為請求失敗*/code: number;/*** 響應信息*/msg?: string;/*** 響應時間*/resTime?: Date;result?: R;tips?: string;
}
/*** 登錄VO*/
export interface LoginResult {/*** 訪問token,有效期1小時*/accessToken?: string;/*** 頭像*/avatar?: string;/*** 昵稱*/nickname?: string;/*** 續期token,有效期30天*/renewalToken?: string;
}
Button('泛型參數-約束post請求參數').onClick(async () => {// 第三個泛型參數:約束請求體(data)參數的類型 - 重點// res的類型由第二個參數來決定// 第一個泛型參數:會被覆蓋掉const res = await axios.post<null, AxiosResponse<ServiceResponse<LoginResult>, null>, PostUserLoginPasswdData>('https://guardian-api.itheima.net/user/login/passwd',{"phone": "120666666672","passwd": "888itcast.CN764%..."})promptAction.showToast({message: '登錄請求發送成功'})//AlertDialog.show({message: JSON.stringify(res, null, 2)})if (res.data.code === 200) {this.avatar = res.data.result?.avatar as string} else {}})
Image(this.avatar).width(200)
Divider().strokeWidth(1)
2.axios攔截器
在請求或響應被then或catch處理前攔截它們
Button('創建axios實例').onClick(async () => {// 0.創建axios實例const axiosInstance = axios.create({baseURL: 'https://guardian-api.itheima.net',timeout: 20 * 1000 //超時時間})// 注意復制過來攔截器的結構后,把axios替換成axiosInstance 實例// 1.axios請求攔截器axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => {config.headers.Authorization = 'token_xxxx'console.log('interceptors request', JSON.stringify(config));return config},(error: AxiosError) => {return Promise.reject(error)})//2.添加相應攔截器axiosInstance.interceptors.response.use(//對響應數據做點兒什么(response: AxiosResponse) => {return response},(error: AxiosError) => {//對響應錯誤做點兒什么return Promise.reject(error)});// -----const res = await axiosInstance.post<null, AxiosResponseData<LoginResult>, PostUserLoginPasswdData> ('/user/login/passwd', {phone: '120666666672',passwd: '888itcast.CN764%...'})if (res.data.code === 200) {this.avatar = res.data.result?.avatar as string} else {promptAction.showToast({message: res.data.msg})}})
3.請求工具封裝
統一處理業務狀態碼錯誤
// http.ets
import axios, { AxiosResponse, InternalAxiosRequestConfig, AxiosError } from '@ohos/axios'
import { promptAction } from '@kit.ArkUI';/*** 后端響應基本類型*/
export interface ServiceResponse<T> {/** 請求碼,200為成功,300及300以上為請求失敗 */code: number;msg: string;resTime: Date;result: T;tips: string;
}// type 類型別名, 保存類型
// 三層對象嵌套:Axios 響應類型 > 后端響應基本類型 > 不同接口響應的類型
export type AxiosResponseData<Result = null> = AxiosResponse<ServiceResponse<Result>, null>export const axiosInstance = axios.create({baseURL: 'https://guardian-api.itheima.net',timeout: 1000*20
})// 添加請求攔截器
axiosInstance.interceptors.request.use((config:InternalAxiosRequestConfig) => {// 對請求數據做點什么return config;
}, (error:AxiosError) => {// 對請求錯誤做些什么return Promise.reject(error);
});// 添加響應攔截器
axiosInstance.interceptors.response.use((response:AxiosResponseData)=> {if (response.data.code == 200) {return response;} else {promptAction.showToast({message: response.data.msg})return Promise.reject() // 中斷await后續代碼的執行}// 對響應數據做點什么return response;
}, (error:AxiosError)=> {// 對響應錯誤做點什么return Promise.reject(error);
});
//Index.ets
Button('請求工具-發送登錄請求').onClick(async () => {const res = await axiosInstance.post<null,AxiosResponseData<LoginResult>, PostUserLoginPasswdData>('/user/login/passwd',{phone: '111', passwd: '222'})//直接書寫參數正確時的邏輯即可,錯誤由攔截器統一處理this.avatar = res.data.result?.avatar as stringAlertDialog.show({message: JSON.stringify(res, null, 2)})})
統一處理401或404錯誤
interface GetUserMeResponse {avatar?: string;nickname?: string;
}
Button('請求工具-發送獲取我的用戶信息').onClick( async () => {const res = await axiosInstance.get<null,AxiosResponseData<GetUserMeResponse>>('/user/me')this.avatar = res.data.result?.avatar as string
})
Button('請求工具-測試錯誤url路徑').onClick(async () => {await axiosInstance.get('/user/meee')
})
// 添加響應攔截器
axiosInstance.interceptors.response.use((response:AxiosResponseData)=> {if (response.data.code == 200) {return response;} else {promptAction.showToast({message: response.data.msg})return Promise.reject() //中斷await后續代碼的執行}// 對響應數據做點什么return response;
}, (error:AxiosError)=> {// 401錯誤統一處理if(error.message.includes('401')) {promptAction.showToast({message: '登錄信息無效,請重新登錄'})} else if (error.message.includes('404')) {promptAction.showToast({message: '請求地址無效'})} else {promptAction.showToast({message: '未知網絡錯誤'})}// 清空無效的用戶信息// 對響應錯誤做點什么return Promise.reject(error);
});