AxiosRequest.ets 5.78 KB
import axios, {
  AxiosError,
  AxiosInstance,
  AxiosResponse,
  HttpStatusCode,
  InternalAxiosRequestConfig
} from '@ohos/axios';
import { Logger } from 'wdKit/Index';
import { ResposeError } from '../bean/ResposeError';

// import type ResponseDTO from '../models/ResponseDTO';

// const key = 'xxxxyyyyzzz'

// const apiBaseUrl = 'http://127.0.0.1:5566'
// const apiBaseUrl = "https://display-sc.miguvideo.com/display/v3/static";
// console.log("apiBaseUrl:" + apiBaseUrl);
// axios.defaults.baseURL = apiBaseUrl

// 使跨域请求带上cookie等用户认证凭据
// axios.defaults.withCredentials = true;

// 实例化axios
const instance: AxiosInstance = axios.create({
  // axios请求基础URL(包括端口号)
  // baseURL: apiBaseUrl,
  // 单位毫秒
  timeout: 15000,
  // 跨域请求时,携带cookie等用户认证凭据
  // withCredentials: true
});

const TAG = "HttpRequest"

// 添加请求拦截器
instance.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 在发送请求之前
    if (!config.headers["Content-Type"]) {
      config.headers["Content-Type"] = "application/json;charset=utf-8";
    }
    // 公共请求参数
    // config.params.key = key
    Logger.debugOptimize(TAG, () => {
      return 'request: ' + config.url
    })
    return config;
  },
  (error: AxiosError) => {
    // 请求错误
    Logger.error(`全局请求失败拦截,message:${error.message}`)
    return Promise.reject(error);
  }
);

// // GET /api/success
// {
//   "code": 0,
//   "message": "请求成功",
//   "data": {
//     "name": "管理员"
//   }
// }
// // GET /api/fail
// {
//   "code": -1,
//   "message": "请求失败:XXX错误!",
//   "data": null
// }

// 添加响应拦截器
instance.interceptors.response.use(// 响应拦截器response类型就是Axios.request<T = any, R = AxiosResponse<T>, D = any>中的泛型R
  // 泛型 T 就是服务器返回数据的类型
  // 泛型 R 就是这个泛型 T 数据经过 axios 包装一层得到的 response 对象的类型,而 request 方法的返回值是一个 Promise,其值就是成功态的 R,也就是 response对象。
  (response: AxiosResponse) => {
    // response为AxiosResponse类型,含有config\data\headers\request\status\statusText属
    // console.dir(response)
    // 正常响应,可对响应数据做通用处理
    // 2xx 范围内的状态码都会触发该函数。
    if (response.status === HttpStatusCode.Ok) {
      // 直接返回response,当然你也可以只返回response.data
      // return response;
      // 也可以先解析服务器返回的状态码,可判断code处理通用逻辑
      // const { code, message, data } = response.data
      // if (code === 0) {
      //   // 将组件用的数据返回
      //   return data
      // } else {
      //   // 处理业务错误。
      //   console.log(`处理业务,message:${message}`)
      //   return Promise.reject(new Error(message))
      // }
      // const data: ResponseBean<any> = response.data

      Logger.debug(TAG, 'response ==============start=================')
      Logger.debugOptimize(TAG, () => {
        return 'response: ' + JSON.stringify(response.data)
      })
      Logger.debug(TAG, 'response ==============end=================')
      // 改造返回的数据,即将AxiosResponse的data返回,服务端返回的数据
      return response.data;
    } else {
      Logger.error(TAG, `httpStatus:${response.status}-${response.status}!`)
      // return Promise.reject(error);
      return response.data;
    }
  },
  (error: AxiosError) => {
    // 异常响应
    // 429-流量超标;403-临时token;406-token过期,强制下线
    // 这里用来处理http常见错误,进行全局提示
    let errorBean = new ResposeError()
    if (error != null && error.response != null) {
      let message = buildErrorMsg(error.response.status);
      // 错误消息可以使用全局弹框展示出来
      Logger.error(`httpStatus:${error.response?.status}-${message},请检查网络或联系管理员!`)
      errorBean = buildError(error.response.status)
    }
    return Promise.reject(errorBean);
  }
);

export default instance;

function buildErrorMsg(httpStatus: number): string {
  let message = "";
  switch (httpStatus) {
    case HttpStatusCode.BadRequest:
      message = "请求错误(400)";
      break;
    case HttpStatusCode.Unauthorized:
      message = "未授权(或token 失效),请重新登录(401)";
    // 可以触发退出的 action
    // 可以做清空storage并跳转到登录页的操作
      break;
    case HttpStatusCode.Forbidden:
      message = "拒绝访问(403)";
      break;
    case HttpStatusCode.NotFound:
      message = "请求出错(404)";
    // 请求地址错误
      break;
    case HttpStatusCode.RequestTimeout:
      message = "请求超时(408)";
      break;
    case HttpStatusCode.InternalServerError:
      message = "服务器错误(500)";
    // 服务器故障
      break;
    case HttpStatusCode.NotImplemented:
      message = "服务未实现(501)";
      break;
    case HttpStatusCode.BadGateway:
      message = "网络错误(502)";
      break;
    case HttpStatusCode.ServiceUnavailable:
      message = "服务不可用(503)";
      break;
    case HttpStatusCode.GatewayTimeout:
      message = "网络超时(504)";
      break;
    case HttpStatusCode.HttpVersionNotSupported:
      message = "HTTP版本不受支持(505)";
      break;
    default:{
      // 网络连接故障
      if(httpStatus != undefined){
        message = `连接出错(${httpStatus})!`;
      }else{
        message = `网络出小差了,请检查网络后重试`;
      }
    }

  }
  return message;
}

function buildError(httpStatus: number): ResposeError {
  let message = buildErrorMsg(httpStatus);
  let error: ResposeError = ResposeError.buildError(message, httpStatus)
  return error;
}