ts
复制代码
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig, Method } from '@ohos/axios';
import { GlobalThis, Logger, StringBuilder, StrUtil, ToastUtil } from '@yunkss/eftool';
import { ResponseBaseResult, ResponseResult } from '../model/ResponseResult';
import { deviceInfo, emitter, systemDateTime } from '@kit.BasicServicesKit';
import { ContentType } from '../constant/CommonConstant';
import { HttpConstant } from '../constant/HttpConstant';
import { HttpConfig } from '../utils/HttpConfig';
import { UserManager } from './UserManager';
import { buffer, TreeMap, util } from '@kit.ArkTS';
import { CryptoConstant } from '../constant/CryptoConstant';
import BuildProfile from '../../../../BuildProfile';
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { EmitterConstants } from '../constant/EmitterConstants';
import loadingManager from './LoadingManager';
import crypto from '@ohos.security.cryptoFramework';
const TAG: string = "HttpUtil: "
const PUBLIC_KEY = "MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGj8WNUSzCn0rHqfIXk9XPdJp60u\n" +
"JnM+mVZVxY1lZmUCVA7t3eJZ0R0z1hUHkVb51eryDZcsz0QLSav3cmQv00ullK18\n" +
"8aOs2SXZe6rcQf6XmOsVBqgADkrN+WePZJmb5Fr0NUkQ/sr7+R71cDZ87Y9QKm99\n" +
"8BFOiWoEGxWWvDsTAgMBABF=";
export function httpDefaultSetting() {
// default settings
axios.defaults.baseURL = HttpConfig.BASE_URL;
axios.defaults.timeout = HttpConstant.HTTP_TIMEOUT;
// default headers
//设备相关
axios.defaults.headers.common['os'] = 'harmoney';
axios.defaults.headers.common['device'] = deviceInfo.marketName;
//用户相关
axios.defaults.headers.common["token"] = UserManager.getToken();
axios.defaults.headers.common["Authorization"] = UserManager.getToken();
// for post
axios.defaults.headers.post['Content-Type'] = ContentType.APPLICATION_JSON
// 添加请求拦截器
axios.interceptors.request.use((config: InternalAxiosRequestConfig) => {
return transRequest(config);
}, (error: AxiosError) => {
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use((response: AxiosResponse) => {
return transResponse(response);
}, (error: AxiosError) => {
return Promise.reject(error);
});
}
/**
* 在这里处理请求体的拦截器操作逻辑
*/
async function transRequest(config: InternalAxiosRequestConfig): Promise<InternalAxiosRequestConfig> {
try {
Logger.debug(TAG, "------------------Request------------------");
Logger.debug(TAG, "httpUrl: " + config.baseURL + config.url);
Logger.debug(TAG, "headers: " + JSON.stringify(config.headers));
syncCryptoDataBySys(config)
} catch (error) {
let e: Error = error as Error
Logger.error(TAG, e.message)
} finally {
return config;
}
}
/**
* 在这里处理请求结果的拦截器操作逻辑
*/
function transResponse(response: AxiosResponse): AxiosResponse {
try {
if (isSuccess(response)) {
let data: ResponseBaseResult = response.data as ResponseBaseResult
switch (data.code) {
case HttpConstant.HTTP_OK:
case HttpConstant.HTTP_OK_200:
break
case HttpConstant.HTTP_LOGOUT:
// 退出登录
emitter.emit({ eventId: EmitterConstants.LOGIN_OUT }, {
data: {
msg: data.msg,
}
});
break
default:
if (data.msg != null && data.msg.length != 0) {
ToastUtil.showToast(data.msg)
}
break
}
} else {
ToastUtil.showToast(!StrUtil.isEmpty(response.statusText) ? response.statusText : $r('app.string.http_error_msg'))
}
return response;
} catch (error) {
let e: Error = error as Error
ToastUtil.showToast(!StrUtil.isEmpty(e.message) ? e.message : $r('app.string.http_error_msg'))
return response;
}
}
export function httpGet<D>(url: string, config?: AxiosRequestConfig<D>,): Promise<D> {
Logger.debug(TAG, "httpGet: ");
let uiContext = GlobalThis.getInstance().getContext("EntryAbility")?.windowStage.getMainWindowSync().getUIContext()
if (uiContext != undefined) {
loadingManager.show(uiContext)
}
return new Promise<D>((resolve: Function, reject: Function) => {
let startTime = systemDateTime.getTime()
axios.get<ResponseResult<D>, AxiosResponse<ResponseResult<D>>, null>(url, {
baseURL: config?.baseURL,
headers: config?.headers,
// 指定请求超时的毫秒数(0 表示无超时时间)
timeout: HttpConstant.HTTP_TIMEOUT,
params: config?.params,
})
.then((response: AxiosResponse<ResponseResult<D>>) => {
let duration = (systemDateTime.getTime() - startTime).toString()
Logger.debug(TAG, "------------------Response------------------");
Logger.debug(TAG, "httpUrl" + config?.baseURL + config?.url);
Logger.debug(TAG, "httpGet Success duration=" + duration);
Logger.debug(TAG, "config=" + JSON.stringify(response.config));
Logger.debug(TAG, "status=" + response.status);
Logger.debug(TAG, "headers=" + JSON.stringify(response.headers));
Logger.debug(TAG, "data=" + JSON.stringify(response.data));
Logger.debug(TAG, "-------------------------------------------");
if (isSuccess(response)) {
if (isResultSuccess(response.data)) {
resolve(response.data.data);
} else {
const e: Error = { name: `${response.data.code}`, message: `${response.data.msg}` }
reject(e);
}
} else {
const e: Error = { name: `${response.status}`, message: `${response.statusText}` }
reject(e);
}
loadingManager.hide()
})
.catch((reason: AxiosError) => {
Logger.error(TAG, "httpUrl" + config?.baseURL + config?.url);
Logger.error(TAG, JSON.stringify(reason));
reject(reason)
loadingManager.hide()
})
});
}
export function httpPost<D>(url: string, data?: ESObject, config?: AxiosRequestConfig<D>,
isFormUrlencoded: boolean = true): Promise<D> {
let uiContext = GlobalThis.getInstance().getContext("EntryAbility")?.windowStage.getMainWindowSync().getUIContext()
if (uiContext != undefined) {
loadingManager.show(uiContext)
}
return new Promise<D>((resolve: Function, reject: Function) => {
let startTime = systemDateTime.getTime()
let requestData: ESObject = isFormUrlencoded ? getRequestFormData(data ?? config?.data) : data ?? config?.data
axios.post(
url,
requestData,
{
baseURL: config?.baseURL,
headers: buildPostRequestHeader(isFormUrlencoded, config?.headers),
// 指定请求超时的毫秒数(0 表示无超时时间)
timeout: HttpConstant.HTTP_TIMEOUT,
params: config?.params,
}
)
.then((response: AxiosResponse<ResponseResult<D>>) => {
let duration = (systemDateTime.getTime() - startTime).toString()
Logger.debug(TAG, "------------------Response------------------");
Logger.debug(TAG, "httpUrl" + config?.baseURL + config?.url);
Logger.debug(TAG, "httpPost Success duration=" + duration);
Logger.debug(TAG, "config=" + JSON.stringify(response.config));
Logger.debug(TAG, "status=" + response.status);
Logger.debug(TAG, "headers=" + JSON.stringify(response.headers));
Logger.debug(TAG, "data=" + JSON.stringify(response.data));
Logger.debug(TAG, "-------------------------------------------");
if (isSuccess(response)) {
if (isResultSuccess(response.data)) {
resolve(response.data.data);
} else {
const e: Error = { name: `${response.data.code}`, message: `${response.data.msg}` }
reject(e);
}
} else {
const e: Error = { name: `${response.status}`, message: `${response.statusText}` }
reject(e);
}
loadingManager.hide()
})
.catch((reason: AxiosError) => {
Logger.error(TAG, "httpUrl" + config?.baseURL + config?.url);
Logger.error(TAG, JSON.stringify(reason));
reject(reason)
loadingManager.hide()
})
})
}
export function httpRequest<D>(url: string, method?: Method | string, data?: D,
config?: AxiosRequestConfig<D>): Promise<ResponseResult<D>> {
let uiContext = GlobalThis.getInstance().getContext("EntryAbility")?.windowStage.getMainWindowSync().getUIContext()
if (uiContext != undefined) {
loadingManager.show(uiContext)
}
return new Promise<ResponseResult<D>>((resolve: Function, reject: Function) => {
let startTime = systemDateTime.getTime()
axios.request<ResponseResult<D>, AxiosResponse<ResponseResult<D>>, D>({
url: url,
method: method,
baseURL: config?.baseURL,
headers: config?.headers,
// 指定请求超时的毫秒数(0 表示无超时时间)
timeout: HttpConstant.HTTP_TIMEOUT,
params: config?.params,
data: data ?? config?.data
})
.then((response: AxiosResponse<ResponseResult<D>>) => {
let duration = (systemDateTime.getTime() - startTime).toString()
Logger.debug(TAG, "------------------Response------------------");
Logger.debug(TAG, "httpUrl" + config?.baseURL + config?.url);
Logger.debug(TAG, "httpRequest Success duration=" + duration);
Logger.debug(TAG, "config=" + JSON.stringify(response.config));
Logger.debug(TAG, "status=" + response.status);
// Logger.debug(TAG, "statusText=" + response.statusText); // always empty??
Logger.debug(TAG, "headers=" + JSON.stringify(response.headers));
Logger.debug(TAG, "data=" + JSON.stringify(response.data));
Logger.debug(TAG, "-------------------------------------------");
if (isSuccess(response)) {
if (isResultSuccess(response.data)) {
resolve(response.data.data);
} else {
const e: Error = { name: `${response.data.code}`, message: `${response.data.msg}` }
reject(e);
}
} else {
const e: Error = { name: `${response.status}`, message: `${response.statusText}` }
reject(e);
}
loadingManager.hide()
})
.catch((reason: AxiosError) => {
Logger.error(TAG, "httpUrl" + config?.baseURL + config?.url);
Logger.error(TAG, JSON.stringify(reason));
reject(reason)
loadingManager.hide()
})
});
}
function getRequestFormData(data?: ESObject): string | undefined {
if (data == undefined) {
return undefined;
}
let sb = new StringBuilder();
let keys = Object.keys(data);
keys.forEach((key: string) => {
sb.append(`${key}=${data[key]}`)
if (keys.indexOf(key) != keys.length - 1) {
sb.append('&')
}
})
let formData = sb.toString();
return formData;
}
function buildPostRequestHeader(isFormUrlencoded: boolean,
headers?: Record<ESObject, ESObject>): Record<ESObject, ESObject> {
if (headers != null) {
headers['Content-Type'] = isFormUrlencoded ? ContentType.APPLICATION_FORM : ContentType.APPLICATION_JSON
return headers
}
return {
'Content-Type': isFormUrlencoded ? ContentType.APPLICATION_FORM : ContentType.APPLICATION_JSON,
}
}
function isSuccess(response: AxiosResponse): boolean {
return response.status >= 200 && response.status < 300
}
function isResultSuccess(result: ResponseBaseResult): boolean {
return result.code == HttpConstant.HTTP_OK
}
// 同步加密数据
export function syncCryptoDataBySys(config: InternalAxiosRequestConfig) {
let treeMap: TreeMap<string, string> = new TreeMap()
if (config.headers['Content-Type'] == ContentType.APPLICATION_FORM) {
let data = StrUtil.asString(config.data);
let params: string[] | undefined = data?.split("&");
if (params != undefined) {
params.forEach(param => {
let paramKV: string[] = param.split("=");
treeMap.set(paramKV[0], paramKV[1]);
})
}
} else {
let keys = Object.keys(config.data);
keys.forEach((key: string) => {
treeMap.set(key, config.data[key]);
})
}
let obj: Record<string, string> = {};
for (let entry of treeMap.entries()) {
obj[Object(entry)[0]] = Object(entry)[1];
}
//参数排序后序列化
let jsonParams: string = JSON.stringify(obj)
Logger.debug(TAG, jsonParams)
//AES加密
//创建秘钥生成器
let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256')
// 通过非对称密钥生成器,随机生成非对称密钥
let promiseSymKey = symKeyGenerator.generateSymKeySync();
//转换成可以读懂的字符串
let key = buffer.from(promiseSymKey.getEncoded().data).toString('hex').substring(0, 32);
//创建iv
let iv = key.substring(0, 16);
let ivParam: cryptoFramework.IvParamsSpec = {
algName: 'IvParamsSpec',
iv: {
data: new Uint8Array(buffer.from(iv).buffer)
}
}
//convertKey方法是通过秘钥生成symKey
let symKey = symKeyGenerator.convertKeySync({ data: new Uint8Array(buffer.from(key).buffer) });
//创建cipher
let cipher = cryptoFramework.createCipher('AES256|CBC|PKCS7');
//创建cipher之后才能初始化
cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ivParam);
let output = cipher.doFinalSync({ data: new Uint8Array(buffer.from(jsonParams, 'utf-8').buffer) })
let base64: util.Base64Helper = new util.Base64Helper();
//加密后的数据
let aesParams = base64.encodeToStringSync(output.data);
//写入请求体
config.data = encodeURIComponent(CryptoConstant.SIGN) + "=" + encodeURIComponent(aesParams);
//RSA加密aes秘钥
//将公钥转换
let symKeyBlob: crypto.DataBlob = { data: base64.decodeSync(PUBLIC_KEY) };
let aesGenerator = crypto.createAsyKeyGenerator('RSA1024');
let pubPair = aesGenerator.convertKeySync(symKeyBlob, null);
//生成加密器
let encoder = crypto.createCipher('RSA1024|PKCS1');
//初始化加密环境
encoder.initSync(crypto.CryptoMode.ENCRYPT_MODE, pubPair.pubKey, null);
//封装加密所需数据
let encode = new util.TextEncoder();
//开始加密
let updateOutput = encoder.doFinalSync({ data: encode.encodeInto(key) });
//转换字符串
let rsaKay = buffer.from(updateOutput.data).toString("base64");
//写入请求头
config.headers[CryptoConstant.PRIVATE_KEY] = rsaKay;
Logger.debug(TAG, CryptoConstant.SIGN + ": " + aesParams)
Logger.debug(TAG, CryptoConstant.PRIVATE_KEY + ": " + rsaKay)
}
// 同步加密数据
export function syncCryptoDataByRSA(data: string): string {
//RSA加密aes秘钥
//将公钥转换
let base64: util.Base64Helper = new util.Base64Helper();
let symKeyBlob: crypto.DataBlob = { data: base64.decodeSync(PUBLIC_KEY) };
let aesGenerator = crypto.createAsyKeyGenerator('RSA1024');
let pubPair = aesGenerator.convertKeySync(symKeyBlob, null);
//生成加密器
let encoder = crypto.createCipher('RSA1024|PKCS1');
//初始化加密环境
encoder.initSync(crypto.CryptoMode.ENCRYPT_MODE, pubPair.pubKey, null);
//封装加密所需数据
let encode = new util.TextEncoder();
//开始加密
let updateOutput = encoder.doFinalSync({ data: encode.encodeInto(data) });
//转换字符串
return buffer.from(updateOutput.data).toString("base64");
}