为了提高http请求数据的泛化性能,该封装方法对于返回数据进行了泛型定义,便于提高复用性。
一、定义url基地址并引入http和自定义返回数据类型
import { http } from '@kit.NetworkKit'
import { iLoginDataModel, iResponseModel } from '../../models/AccountModel'
import { promptAction, router } from '@kit.ArkUI'
const baseUrl: string = 'https://xxx.xxxxx.net/' // url的基地址
二、封装Hdhttp类,注入get、post等方法
export class HdHttp {
// 静态的 get泛型方法
static async get<T>(url: string) {
try {
// 2.0 发请求
const httpRequest = http.createHttp()
url = baseUrl + url
// 获取token
// 获取token,判断如果有token,则传,否则不传
let user = AppStorage.get('user') as iLoginDataModel
let token = user?.token // 可选 【可空]类型
//异步执行,用await获取返回数据
let res = await httpRequest.request(url, {
method: http.RequestMethod.GET,
header: {
'Authorization': `Bearer ${token}`
},
expectDataType: http.HttpDataType.OBJECT
})
// 响应
// 判断如果响应code为401则提示用户token失效,直接跳转到登录页面让用户重新登录
let resData = res.result as iResponseModel<T>
if(resData.code === 401){
promptAction.showToast({ message: '登录超时,请重新登录' })
router.pushUrl({url:'pages/LoginPage'})
}
return resData
} catch (err) {
promptAction.showToast({ message: 'get网络错误' })
return Promise.reject(err) // 如果报错则将错误返回
}
}
// 2.1 静态的post泛型方法
// url: 请求url地址
// extraData:post请求体的参数,因为不是每个url都要求传递,所以定义为可选参数
/* 封装思路:
固定代码写死,可变的地方提炼成参数供外部调用的时候传入
* */
static async post<T>(url: string, extraData?: Object) {
try {
// 创建http对象
const httpRequest = http.createHttp()
// 完整拼接url地址
url = baseUrl + url
// 设置请求参数
let options: http.HttpRequestOptions = {
method: http.RequestMethod.POST,
header: {
"Content-Type": 'application/json'
},
expectDataType: http.HttpDataType.OBJECT // http模块底层将服务器响应回来的json字符串自动调用JSON.parse转成对象
}
// 判断如果extraData有值,则向options对象增加一个extraData的属性
if (extraData) {
options.extraData = extraData
}
// 获取token,判断如果有token,则传,否则不传
let user = AppStorage.get('user') as iLoginDataModel
let token = user?.token // 可选 【可空]类型
if (token && options.header) {
options.header['Authorization'] = `Bearer ${token}`
}
// 调用reqeust方法并且指定相应的参数
let res = await httpRequest.request(url, options)
// 响应服务器的数据
// 由于不同的接口返回的数据类型不一样,所以此方法应该用一个泛型来替代,将来实际运行的时候是什么类型就返回什么类型
// 判断如果响应code为401则提示用户token失效,直接跳转到登录页面让用户重新登录
let resData = res.result as iResponseModel<T>
if(resData.code === 401){
promptAction.showToast({ message: '登录超时,请重新登录' })
router.pushUrl({url:'pages/LoginPage'})
}
return resData
} catch (err) {
promptAction.showToast({ message: 'post网络错误' })
return Promise.reject(err) // 如果报错则将错误返回
}
}
}