怀念夏天 发表于 2024-10-7 05:57:32

鸿蒙Harmony应用开辟,数据驾驶舱网络请求(Axios) 封装

鸿蒙Harmony应用开辟,数据驾驶舱网络请求(Axios) 封装

在进行网络请求的封装之前,先来分析一下我们项目所用到的接口的基本环境: 1. 在请求的接口中添加了署名。
2.在非登录接口中添加了token。 基于以上基本的环境。我们开始来对Axios做封装。
首先我们必要在根目录的oh-package.json5文件的dependencies中添加 axios的依靠
"@ohos/axios": "^2.1.1",
前面我们已经介绍了我们的接口请求中的2个必要因素是署名和token,如今我们开始对这2块的实现开始介绍


[*] 署名的生成
我们的署名是将当前所有的请求参数加被骗前的时间戳来生成的署名,以是们把请求中的参数做遍历放到一个数组中
在添加一个当前时间戳,以及生成的署名作为新的请求参数
private generateSignature(params: RequestParams): RequestParams {
const time = Date.now().toString().substr(0, 10);
let str = pref + "&";

const allParams: RequestParams = {};
Object.keys(params).forEach((key) => {
 allParams = params;
});
allParams['timestamp'] = time;

const sortedKeys = Object.keys(allParams).sort();

sortedKeys.forEach((key) => {
 const value = allParams;
 if (typeof value !== 'object' && value !== null) {
   if (key === "timestamp") {
     str += `${key}=${time}&`;
   } else if (key !== "sign") {
     str += `${key}=${decodeURIComponent(String(value))}&`;
   }
 }
});
str += suff;
allParams['sign'] = CryptoJS.MD5(str).toString()
return allParams
}


[*] 请求头token
我们在登录接口获取到token后存储到preferences中,然后在再请求头添加类似的代码
headers.set('Authorization', token);

接下来我们创建一个PolarisHttp.ets开始对基本的get ,post ,put,patch等方法的封装
首先我们必要创建一个网络请求对象 PolarisHttpRequest,定义基础的变量
config: HttpRequestConfig;//请求配置参数
interceptorHooks?: InterceptorHooks; //拦截器
instance: AxiosInstance; //阿修罗实例
阿修罗网络请求核心代码:
request<T = CommonType>(config: HttpRequestConfig): Promise<T> {
return new Promise<T>((resolve, reject) => {
 this.instance
   .request<CommonType, T>(config)
   .then(res => {
     resolve(res);
   })
   .catch((err: Error) => {
     LogUtils.error("网络请求Request异常:", err.toString());
     if (err instanceof AxiosError) {
       showToast(err.message)
     }
     reject(err);
   });
});
}


[*] GET 请求封装:
public get<T = CommonType>(config: HttpRequestConfig): Promise<T> {// 确保 params 存在if (!config.params) {  config.params = {};}​const allParams: RequestParams = this.generateSignature(config.params);// Object.keys(config.params).forEach(key => {//   allParams = config.params;// });// 创建新的 headers 对象const headers = new AxiosHeaders(config.headers);return new Promise<T>((resolve, reject) => {  const getTokenAndSendRequest = () => {    if (!config.isLoginState) {      UserLoginHelper.getUserToken().then(token => {        if (token && typeof token === 'string') {          LogUtils.error('网络请求Request Authorization', token);          headers.set('Authorization', token);
       } else {          LogUtils.error('网络请求Request 请求未获取的Token信息');        }        sendRequest();      }).catch(reject);    } else {      sendRequest();    }  };  const sendRequest = () => {    // 构建新的配置对象    const newConfig: HttpRequestConfig = {      method: 'GET',      url: config.url,      params: allParams,      headers: headers,      data: config.data,      timeout: config.timeout,      responseType: config.responseType    };    // 发送请求    this.request<T>(newConfig).then(resolve).catch(reject);  };  getTokenAndSendRequest();});}
[*] POST请求封装:
public post<T = CommonType>(config: HttpRequestConfig): Promise<T> {// 确保 data 存在if (!config.data) {  config.data = {};}let allData: RequestParams = {};// 复制原有数据Object.keys(config.data).forEach(key => {  allData = config.data;});// 使用 generateSignature 方法生成署名allData = this.generateSignature(allData);// 创建新的 headers 对象const headers = new AxiosHeaders(config.headers);​// 使用Promise来处置惩罚异步token获取return new Promise<T>((resolve, reject) => {  const getTokenAndSendRequest = () => {    if (!config.isLoginState) {      LogUtils.error('网络请求Request--Authorization...token..!config.isLoginState');      UserLoginHelper.getUserToken().then(token => {        if (token && typeof token === 'string') {          LogUtils.error('网络请求Request--Authorization', token);          headers.set('Authorization', token);
       } else {          LogUtils.error('网络请求Request--Authorization--请求未获取的Token信息');        }        sendRequest();      }).catch(reject);    } else {      LogUtils.error('网络请求Request--Authorization...token..config.isLoginState');      sendRequest();    }  };  const sendRequest = () => {    // 构建新的配置对象    const newConfig: HttpRequestConfig = {      method: 'POST',      url: config.url,      data: allData,      headers: headers,      timeout: config.timeout,      responseType: config.responseType    };    // 发送请求    this.request<T>(newConfig).then(resolve).catch(reject);  };  getTokenAndSendRequest();});​​// // 构建新的配置对象// const newConfig: HttpRequestConfig = {//   method: 'POST',//   url: config.url,//   data: allData,//   headers: headers,//   timeout: config.timeout,//   responseType: config.responseType// };// // 返回请求// return this.request<T>(newConfig);}
我们可以看到上述的get 请求和post请求都用了2次回调,因为我们的 preferences数据的获取是一个异步过程(因为js我不是很熟悉如果你有好的实现,也可以分享下) 我们必要先异步获取到token 然后在添加到请求头中当中去.
使用示例

const httpClient = new PolarisHttpRequest({
 baseURL: 'https://api.example.com',
 timeout: 5000,
 interceptorHooks: {
   requestInterceptor: (config) => {
     // 请求拦截逻辑
     return config;
 },
   responseInterceptor: (response) => {
     // 响应拦截逻辑
     return response;
 }
}
});

// GET请求示例
httpClient.get<ApiResponse<UserInfo>>({
 url: '/user/info',
 params: { userId: 123 }
}).then(response => {
 console.log(response.data);
}).catch(error => {
 console.error(error);
});

// POST请求示例
httpClient.post<ApiResponse<LoginResult>>({
 url: '/user/login',
 data: { username: 'example', password: 'password' }
}).then(response => {
 console.log(response.data);
}).catch(error => {
 console.error(error);
});
注意事项


[*]确保在使用前精确配置baseURL和其他必要的选项。
[*]generateSignature方法使用了特定的署名算法,请根据实际需求调整。
[*]对于差别的环境(开辟、测试、生产),大概必要差别的配置,发起使用环境变量或配置文件管理。
至此,您可以在ArkTS应用中更加方便地管理和发送HTTP请求,同时保证了请求的安全性和一致性。封装类提供的拦截器和错误处置惩罚机制可以大大简化API调用的复杂度。
完整项目下载地点

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 鸿蒙Harmony应用开辟,数据驾驶舱网络请求(Axios) 封装