一 准备工作
1. 先开启一下虚拟机的权限
src/main/module.json5 打开module.json5在15~19行 进行配置网络权限
2. 在终端下载安装一下 ohpm install @ohos/axios
复制 粘贴进去回车就行
3. 这样显示就是安装好了
如果导入不行就关了重新启动
二 创建一个ETS文件,利用静态的泛型方法对axios模块进行统一请求封装(方法名:reqeust,兼容get和post)
axios.reqeust()方法中请求参数提炼和响应泛型提炼
import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from
'@ohos/axios'
import { iResponseModel } from '../models/datamodel'
// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({
baseURL: 'https://juejin.cn/'
})
export class HdHttp {
/*
method:表示服务器的请求方法,Get,POST,PUT,Delete
url:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675
* paramsOrData:请求传参,可选
*
* T:代表的是服务器响应数据中的 data这个属性的类型
* */
static async request<T>(method: string, url: string, paramsOrData?: object) {
try {
// 1. 使用req来发送请求
let reqConfig: AxiosRequestConfig = {
method: method,
url: url, //是请求接口的url路径部分,并且不带有/
}
// 2. 分请求类型来决定传参参数是parmas还是data
if (method == 'GET') {
reqConfig.params = paramsOrData
} else {
reqConfig.data = paramsOrData
}
let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)
// 3. 返回结果(返回的是服务器的响应报文体的数据)
return res.data
} catch (err) {
// 当服务器的http状态码为非200,就会执行catch
let errObj: AxiosError = err
return Promise.reject(errObj.message) // 外面使用者使用try{}catch(err){}
}
}
}
三 增加toke携带和处理非10000的逻辑状态码的响应结果(接口响应正常,但是有逻辑异常,比如用户名或者密码错误)
import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction } from '@kit.ArkUI'
// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({
baseURL: 'https://juejin.cn/'
})
export class HdHttp {
/*
method:表示服务器的请求方法,Get,POST,PUT,Delete
url:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675
* paramsOrData:请求传参,可选
*
* T:代表的是服务器响应数据中的 data这个属性的类型
* */
static async request<T>(method: string, url: string, paramsOrData?: object) {
try {
// 1. 使用req来发送请求
let reqConfig: AxiosRequestConfig = {
method: method,
url: url, //是请求接口的url路径部分,并且不带有/
}
// 2. 分请求类型来决定传参参数是parmas还是data
if (method == 'GET') {
reqConfig.params = paramsOrData
} else {
reqConfig.data = paramsOrData
}
// 3. 在请求前在header中携带token
// 获取token
let user = AppStorage.get<iLoginUserModel>('user')
if (user && user.token) {
reqConfig.headers = {
'Authorization': `Bearer ${user.token}`
}
}
let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)
// 4. 处理服务器响应体中的code值为非10000的情况
if (res.data.code != 10000) {
// 将服务器的逻辑问题信息提示给用户
promptAction.showToast({ message: res.data.message })
return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息
}
// 3. 返回结果(返回的是服务器的响应报文体的数据)
return res.data
} catch (err) {
// 当服务器的http状态码为非200,就会执行catch
let errObj: AxiosError = err
return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}
}
}
}
四 在try{}catch(err){}的catch里面处理状态码为401的时跳转到登录页面,其他状态码时提示用户 errObj.response?.status == 401
import { promptAction, router } from '@kit.ArkUI'
import axios, { AxiosResponse, AxiosError } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { HdHttp } from '../utils/request'
interface iReqBody {
username: string
password: string
}
@Entry
@Component
struct LoginPage {
@State username: string = 'yu123'
@State password: string = 'yu123456'
@State isAgree: boolean = false
@State islogin: boolean = false
// 负责登录
async login() {
// 1. 参数合法性检查
/*
* ● 能对用户名和密码文本框做非空验证处理
● 对用户协议勾选做验证处理
* */
if (this.username == '' || this.password == '') {
return promptAction.showToast({ message: '用户名和密码必填' })
}
if (!this.isAgree) {
promptAction.showToast({ message: '请先勾选协议' })
this.isAgree = true
return
}
// 2. axios请求服务器接口
this.islogin = true
try {
let reqBody = new Object({
username: this.username,
password: this.password
})
let res = await HdHttp.request<iLoginUserModel>('POST', 'hm/login', reqBody)
this.islogin = false
// 3. 处理服务器响应回来的报文体的数据
// 3.1 判断服务器响应体中的code==10000的时候才保存数据,否则提示用户响应体中的message
// if (res.data.code != 10000) {
// return promptAction.showToast({ message: res.data.message })
// }
// 3.2 将服务器响应回来的数据保存到AppStroage中,保存的数据类型是iLoginUserModel
AppStorage.setOrCreate('user', res.data)
// 4. 跳转到首页
router.replaceUrl({ url: 'pages/Index' })
} catch (err) {
this.islogin = false
// 将来服务器的状态码是非200的,就会自动触发catch
let errObj: AxiosError = err //最终将err大错误对象,转为AxiosError
AlertDialog.show({ message: errObj.message }) //最后提示给用户的是message字符串
}
}
build() {
Column() {
// logo
Column({ space: 10 }) {
Image($r('app.media.icon'))
.height(55)
.aspectRatio(1)
}
.margin({ top: 170 })
// 登录区域
Column({ space: 20 }) {
TextInput({ text: $$this.username })
.backgroundColor(Color.White)
.width('90%')
.borderRadius(0)
TextInput({ text: $$this.password })
.type(InputType.Password)
.backgroundColor(Color.White)
.width('90%')
Row() {
Checkbox()
.select(this.isAgree)
.selectedColor('#FA6D1D')
.onChange(value => {
this.isAgree = value
})
Text('已阅读并同意')
.fontSize(14)
.fontColor($r('app.color.ih_gray_color'))
.padding({ right: 4 })
Text('用户协议')
.fontSize(14)
.padding({ right: 4 })
Text('和')
.fontSize(14)
.fontColor($r('app.color.ih_gray_color'))
.padding({ right: 4 })
Text('隐私政策')
.fontSize(14)
.onClick(() => {
router.pushUrl({
url: 'pages/PreviewWebPage'
})
})
}
.width('90%')
Button({ type: ButtonType.Normal }) {
Row() {
if (this.islogin) {
LoadingProgress()
.height(28)
.aspectRatio(1)
.color(Color.White)
}
Text('登录')
}
}
.borderRadius(4)
.width(328)
.height(45)
.fontColor(Color.White)
.linearGradient({
angle: 135,
colors: [
['#FCA21C', 0],
['#FA6D1D', 1]
]
})
.onClick(() => {
this.login()
})
}
.margin({ top: 50 })
}
.width('100%')
.height('100%')
}
}
import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction, router } from '@kit.ArkUI'
// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({
baseURL: 'https://juejin.cn/'
})
export class HdHttp {
/*
method:表示服务器的请求方法,Get,POST,PUT,Delete
url:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675
* paramsOrData:请求传参,可选
*
* T:代表的是服务器响应数据中的 data这个属性的类型
* */
static async request<T>(method: string, url: string, paramsOrData?: object) {
try {
// 1. 使用req来发送请求
let reqConfig: AxiosRequestConfig = {
method: method,
url: url, //是请求接口的url路径部分,并且不带有/
}
// 2. 分请求类型来决定传参参数是parmas还是data
if (method == 'GET') {
reqConfig.params = paramsOrData
} else {
reqConfig.data = paramsOrData
}
// 3. 在请求前在header中携带token
// 获取token
let user = AppStorage.get<iLoginUserModel>('user')
if (user && user.token) {
reqConfig.headers = {
'Authorization': `Bearer ${user.token}`
}
}
let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)
// 4. 处理服务器响应体中的code值为非10000的情况
if (res.data.code != 10000) {
// 将服务器的逻辑问题信息提示给用户
promptAction.showToast({ message: res.data.message })
return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息
}
// 3. 返回结果(返回的是服务器的响应报文体的数据)
return res.data
} catch (err) {
// 当服务器的http状态码为非200,就会执行catch
let errObj: AxiosError = err
// 判断服务器的响应状态码如果是401,表示token失效,此时应该提示用户和跳转到登录页面
if (errObj.response?.status == 401) {
promptAction.showToast({ message: '登录已失效,请重新登录' })
router.replaceUrl({ url: 'pages/LoginPage' })
} else {
// 提示用户是什么错误即可
promptAction.showToast({ message: '网络异常:' + errObj.message })
}
// AlertDialog.show({ message: 'err:' + JSON.stringify(errObj.response?.status, null, 2) })
return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}
}
}
}
五 提炼单独的POST < T > 和 GET< T >来简化对上一步封装好的reqeust方法的调用
封装完成 完整版
import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction, router } from '@kit.ArkUI'
// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({
baseURL: 'https://juejin.cn/'
})
export class HdHttp {
// 这个方法给外面专门做get请求调用的
static async Get<T>(url: string, paramsOrData?: object) {
return await HdHttp.request<T>('GET', url, paramsOrData)
}
// 这个方法给外面专门做post请求调用的
static async Post<T>(url: string, paramsOrData?: object) {
return await HdHttp.request<T>('POST', url, paramsOrData)
}
/*
method:表示服务器的请求方法,Get,POST,PUT,Delete
url:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675
* paramsOrData:请求传参,可选
*
* T:代表的是服务器响应数据中的 data这个属性的类型
* */
private static async request<T>(method: string, url: string, paramsOrData?: object) {
try {
// 1. 使用req来发送请求
let reqConfig: AxiosRequestConfig = {
method: method,
url: url, //是请求接口的url路径部分,并且不带有/
}
// 2. 分请求类型来决定传参参数是parmas还是data
if (method == 'GET') {
reqConfig.params = paramsOrData
} else {
reqConfig.data = paramsOrData
}
// 3. 在请求前在header中携带token
// 获取token
let user = AppStorage.get<iLoginUserModel>('user')
if (user && user.token) {
reqConfig.headers = {
'Authorization': `Bearer ${user.token}`
}
}
let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)
// 4. 处理服务器响应体中的code值为非10000的情况
if (res.data.code != 10000) {
// 将服务器的逻辑问题信息提示给用户
promptAction.showToast({ message: res.data.message })
return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息
}
// 3. 返回结果(返回的是服务器的响应报文体的数据)
return res.data
} catch (err) {
// 当服务器的http状态码为非200,就会执行catch
let errObj: AxiosError = err
// 判断服务器的响应状态码如果是401,表示token失效,此时应该提示用户和跳转到登录页面
if (errObj.response?.status == 401) {
promptAction.showToast({ message: '登录已失效,请重新登录' })
router.replaceUrl({ url: 'pages/LoginPage' })
} else {
// 提示用户是什么错误即可
promptAction.showToast({ message: '网络异常:' + errObj.message })
}
// AlertDialog.show({ message: 'err:' + JSON.stringify(errObj.response?.status, null, 2) })
return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}
}
}
}
总结
以上是我在项目中的用到的关于 axios 的一些封装方法。
以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下:
内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!
鸿蒙【北向应用开发+南向系统层开发】文档
鸿蒙【基础+实战项目】视频
鸿蒙面经
为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!