当前位置: 首页 > article >正文

鸿蒙next之axios二次封装并携带cookie

 

由于官方提供的@ohos.net.http模块,直接使用不是很灵活,就引入了第三方@ohos/axios库。

以下是引入axios并进行二次封装的步骤:

1、DevEco Studio打开终端输入命令安装插件

ohpm install @ohos/axios

 2、新建RequestUtil.ets

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
export { CsPreference } from './CsPreference';
export { CookieManager } from './CookieManager';
CsPreference.ets
本地信息存储
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 全局同步
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>
  }

}


http://www.kler.cn/a/370881.html

相关文章:

  • linux系统监视(centos 7)
  • Agent一键安装,快速上手Zabbix监控!
  • 【网络编程】基础知识
  • Elasticsearch:Jira 连接器教程第一部分
  • 【Linux】进程间通信IPC
  • Spring Boot教程之五十五:Spring Boot Kafka 消费者示例
  • Docker加载并运行别人的容器的同时挂在本地其他文件
  • 影刀RPA与Python作为爬虫的对比
  • 线程的同步
  • MFC实现以不规则PNG图片作为窗口背景
  • IMX6ULL之使用汇编操作GPIO
  • mac 上使用 cmake 构建包含 OpenMP 的项目
  • 网络请求自定义header导致跨域问题
  • 「二叉树进阶题解:构建、遍历与结构转化全解析」
  • 【网络安全】红队人员的GPO和OU指南
  • 端口号和ip地址一样吗?区别是什么
  • [Linux] linux 软硬链接与动静态库
  • 芯片上音频相关的验证
  • 2024前端JS面试题总汇
  • 基于yolov8的布匹缺陷检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】
  • Cisco Packet Tracer 8.0 路由器的基本配置和Telnet设置
  • 《Linux系统编程篇》fork函数——基础篇
  • 基于SSM+小程序的童装商城管理系统(商城3)
  • 用Pyhon写一款简单的益智类小游戏——2048
  • 【338】基于springboot的IT职业生涯规划系统
  • Elasticsearch Serverless 高性价比智能日志分析关键技术解读