由于官方提供的@ohos.net.http模块,直接使用不是很灵活,就引入了第三方@ohos/axios库。
以下是引入axios并进行二次封装的步骤:
1、DevEco Studio打开终端输入命令安装插件
ohpm install @ohos/axios
2、新建RequestUtil.ets
javascript
import { JSON, url } from '@kit.ArkTS';
import { emitter } from '@kit.BasicServicesKit';
import { showToast } from '../../common/utils/ToastUtil';
import { CommonType } from '../utils/TypeUtil';
import { CaresPreference,CookieManager } from './common';
import Constants, { ContentType } from '../../common/constants/Constants';
import axios,{InternalAxiosRequestConfig, AxiosResponse,AxiosError,AxiosRequestConfig,AxiosInstance} from '@ohos/axios';
// 发送订阅事件
function sendEmitter(eventId: number, eventData: emitter.EventData) {
// 定义事件,事件优先级为HIGH
let event: emitter.InnerEvent = {
eventId: eventId,
priority: emitter.EventPriority.HIGH
};
// 发送事件
emitter.emit(event, eventData);
}
export const BASE_URL = `${Constants.BASE_SERVER}`;
// 处理40开头的错误
export function errorHandler(error: CommonType) {
if (error instanceof AxiosError) {
switch (error.status) {
// 401: 未登录
case 401:
break;
case 403: //无权限未登录
// 弹出登录页
let eventData: emitter.EventData = {
data: {
isShow: true
}
};
sendEmitter(Constants.EVENT_LOGIN_PRESENT, eventData)
break;
// 404请求不存在
case 404:
showToast("网络请求不存在")
break;
// 其他错误,直接抛出错误提示
default:
showToast(error.message)
}
}
}
// 创建实例
const service: AxiosInstance = axios.create({
baseURL: '',
timeout: Constants.HTTP_READ_TIMEOUT, //超时时间
withCredentials: true, // 跨域请求是否需要携带 cookie
headers: { // `headers` 是即将被发送的自定义请求头
'Content-Type': 'application/json;charset=utf-8'
}
})
let caresPreference: CaresPreference = CaresPreference.getInstance();
// 请求拦截器
service.interceptors.request.use(async(config:InternalAxiosRequestConfig) => {
let Cookie: string = '';
const cookie = await caresPreference.getValueAsync<string>('APP_Cookies');
if(cookie){
Cookie = cookie;
}
// 由于存储的cookie是这样的'SSOSESSION=OWEwMTBlOTktNjQ2Yy00NDQ1LTkyMTctZTc3NWY2Nzg5MGM2; Path=/; HttpOnly'
// axios网络框架携带的cookie要这种SSOSESSION=OWEwMTBlOTktNjQ2Yy00NDQ1LTkyMTctZTc3NWY2Nzg5MGM2
// 接口才能请求通过(在cookie设置这里卡了挺长时间,鸿蒙自带的http请求带上Path=/; HttpOnly是可以请求通过的,axios要去掉Path=/; HttpOnly)
config.headers['Cookie'] = String(Cookie).split(';')[0];
return config;
}, (error:AxiosError) => {
console.info('全局请求拦截失败', error);
Promise.reject(error);
});
// 响应拦截器
service.interceptors.response.use((res:AxiosResponse)=> {
console.info('响应拦截====',JSON.stringify(res))
const config:AxiosRequestConfig = res.config;
// 获取登录接口cookie,并进行存储
if(config?.url && config?.url.includes('login') && `${JSON.stringify(res.headers['set-cookie'])}`.includes('SSOSESSION')){
let urlObj = url.URL.parseURL(config?.baseURL);
let cookies:CommonType = res.headers['set-cookie'] as CommonType;
if(cookies){
CookieManager.saveCookie(urlObj.host, String(cookies))
}
let sss = CookieManager.getCookies()
console.info(urlObj.host + sss)
caresPreference.setValueAsync('APP_Cookies', res.headers['set-cookie']).then(() => {
console.info('存储cookie:' + res.headers['set-cookie']);
})
return Promise.resolve(res.data);
}
if(res.status === 200){
// 错误返回码
if ( ['40001','40002','40003'].includes(res.data.code)) {
showToast(res.data.message)
} else {
Promise.resolve(res.data);
}
}
return res.data;
}, (error:AxiosError)=> {
console.info("AxiosError",JSON.stringify(error.response))
errorHandler(error.response as AxiosResponse)
return Promise.reject(error);
});
// 导出 axios 实例
export default service;
Common.ets
javascript
export { CsPreference } from './CsPreference';
export { CookieManager } from './CookieManager';
CsPreference.ets
本地信息存储
javascript
import { common } from '@kit.AbilityKit';
import { preferences } from '@kit.ArkData';
const PREFERENCES_NAME: string = 'CS_PREFERENCES';
export class CSPreference {
private preferences: preferences.Preferences;
private context = getContext(this) as common.UIAbilityContext;
private static instance: CsPreference;
constructor() {
this.preferences = preferences.getPreferencesSync(this.context, { name: PREFERENCES_NAME })
}
public static getInstance(): CsPreference {
if (!CsPreference.instance) {
CsPreference.instance = new CsPreference();
}
return CsPreference.instance;
}
setValue(key: string, value: preferences.ValueType) {
if (value != undefined) {
this.preferences.putSync(key, value)
this.preferences.flush()
}
}
getValue(key: string): preferences.ValueType | undefined {
return this.preferences?.getSync(key, undefined)
}
hasValue(key: string): boolean {
return this.preferences.hasSync(key)
}
deleteValue(key: string) {
this.preferences.deleteSync(key)
this.preferences.flush()
}
async initPreference(storeName: string): Promise<void> {
return preferences.getPreferences(this.context, storeName)
.then((preferences: preferences.Preferences) => {
this.preferences = preferences;
});
}
async setValueAsync<T>(key: string, value: T): Promise<void> {
if (this.preferences) {
this.preferences.put(key, JSON.stringify(value)).then(() => {
this.saveUserData();
})
} else {
this.initPreference(PREFERENCES_NAME).then(() => {
this.setValueAsync<T>(key, value);
});
}
}
async getValueAsync<T>(key: string): Promise<T | null> {
if (this.preferences) {
return this.preferences.get(key, '').then((res: preferences.ValueType) => {
let value: T | null = null;
if (res) {
value = JSON.parse(res as string) as T;
}
return value;
});
} else {
return this.initPreference(PREFERENCES_NAME).then(() => {
return this.getValueAsync<T>(key);
});
}
}
async hasValueAsync(key: string): Promise<boolean> {
if (this.preferences) {
return this.preferences.has(key);
} else {
return this.initPreference(PREFERENCES_NAME).then(() => {
return this.hasValue(key);
});
}
}
async deleteValueAsync(key: string): Promise<void> {
if (this.preferences) {
this.preferences.delete(key).then(() => {
this.saveUserData();
});
} else {
this.initPreference(PREFERENCES_NAME).then(() => {
this.deleteValue(key);
});
}
}
saveUserData() {
this.preferences?.flush();
}
}
CookieManager.ets
cookie 全局同步
javascript
import { CsPreference } from './CsPreference'
const GLOBAL_COOKIE: string = "cs_global_cookie"
export class CookieManager {
static removeCookie(host: string) {
let arr = CsPreference.getInstance().getValue(GLOBAL_COOKIE) as Array<string>
if (arr) {
let filteredArray = arr.filter((item)=>{
JSON.parse(item).host != host
})
CsPreference.getInstance().setValue(GLOBAL_COOKIE, filteredArray)
}
}
static saveCookie(host: string, cookie: string) {
CookieManager.removeCookie(host)
let obj: Record<string, Object> = {};
obj["host"] = host;
obj["cookie"] = cookie;
let arr = CsPreference.getInstance().getValue(GLOBAL_COOKIE) as Array<string>
if (arr == undefined) {
arr = new Array<string>()
}
arr.push(JSON.stringify(obj))
CsPreference.getInstance().setValue(GLOBAL_COOKIE, arr)
}
static getCookies(): Array<string>{
return CsPreference.getInstance().getValue(GLOBAL_COOKIE) as Array<string>
}
}