From 7b7ab65b6bebac38c23003aaf8078183e86c7840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E9=98=B3?= Date: Sun, 28 Apr 2024 14:04:09 +0800 Subject: [PATCH] =?UTF-8?q?request=E7=9A=84=E5=AE=9E=E7=8E=B0=E4=BC=98?= =?UTF-8?q?=E5=8C=96=EF=BC=8Crequest=E7=9A=84h5=E7=89=88=E6=9C=AC=E5=A4=8D?= =?UTF-8?q?=E7=94=A8taro-h5=E7=9A=84=E5=AE=9E=E7=8E=B0=EF=BC=8C=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E9=80=9A=E8=BF=87=E6=8E=A5=E5=8F=A3=E5=8F=82=E6=95=B0?= =?UTF-8?q?=EF=BC=8C=E4=B8=9A=E5=8A=A1=E5=8F=AF=E4=BB=A5=E7=81=B5=E6=B4=BB?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=AE=9E=E7=8E=B0=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/apis/NativeApi.ts | 22 +- .../src/api/apis/network/request/index.ts | 98 +---- .../api/apis/network/request/nativeRequest.ts | 98 +++++ .../src/api/apis/osChannelApi.ts | 372 +++++++++--------- 4 files changed, 302 insertions(+), 288 deletions(-) create mode 100644 packages/taro-platform-harmony-hybrid/src/api/apis/network/request/nativeRequest.ts diff --git a/packages/taro-platform-harmony-hybrid/src/api/apis/NativeApi.ts b/packages/taro-platform-harmony-hybrid/src/api/apis/NativeApi.ts index 43b4fc0978b9..52a79e3de019 100644 --- a/packages/taro-platform-harmony-hybrid/src/api/apis/NativeApi.ts +++ b/packages/taro-platform-harmony-hybrid/src/api/apis/NativeApi.ts @@ -1,5 +1,5 @@ import osChannelApi from './osChannelApi' -import { RequestTask } from './request' +// import { RequestTask } from './request' // @ts-ignore const syncAndRelease = window.MethodChannel && window.MethodChannel.jsBridgeMode({ isAsync: false, autoRelease: true }) || (target => target) @@ -880,24 +880,24 @@ class AsyncToSyncProxy { } class HybridProxy { - private readonly useAxios: boolean + // private readonly useAxios: boolean private readonly useOsChannel: boolean private readonly cacheProxy: any - private readonly requestApi = 'request' + // private readonly requestApi = 'request' - constructor (useAxios: boolean, useOsChannel: boolean, nativeApi: NativeApi) { - this.useAxios = useAxios + constructor (useOsChannel: boolean, nativeApi: NativeApi) { + // this.useAxios = useAxios this.useOsChannel = useOsChannel this.cacheProxy = new Proxy(nativeApi, new CacheStorageProxy(nativeApi)) } get (_target: any, prop: string) { return (...args: any) => { - if (this.useAxios && prop === this.requestApi) { - judgeUseAxios = this.useAxios - // @ts-ignore - return new RequestTask(...args) - } + // if (this.useAxios && prop === this.requestApi) { + // judgeUseAxios = this.useAxios + // // @ts-ignore + // return new RequestTask(...args) + // } if (this.useOsChannel && osChannelApi.hasOwnProperty(prop)) { return osChannelApi[prop](...args) } @@ -907,5 +907,5 @@ class HybridProxy { } const nativeApi = new NativeApi() -const native = new Proxy(nativeApi, new HybridProxy(false, false, nativeApi)) // 第一个false是默认走jsb,true是走纯js, 第二个false是不走osChannel +const native = new Proxy(nativeApi, new HybridProxy(false, nativeApi)) // 第一个false是默认走jsb,true是走纯js, 第二个false是不走osChannel export default native diff --git a/packages/taro-platform-harmony-hybrid/src/api/apis/network/request/index.ts b/packages/taro-platform-harmony-hybrid/src/api/apis/network/request/index.ts index ffbea80fc08a..925ba6be4d30 100644 --- a/packages/taro-platform-harmony-hybrid/src/api/apis/network/request/index.ts +++ b/packages/taro-platform-harmony-hybrid/src/api/apis/network/request/index.ts @@ -1,98 +1,14 @@ -import Taro from '@tarojs/api' -import { isFunction } from '@tarojs/shared' +import { request as h5Request } from '@tarojs/taro-h5' +import { request as nativeReuqest } from './nativeRequest' -import { NativeRequest } from '../../interface/NativeRequest' -import native, { judgeUseAxios } from '../../NativeApi' -import { getParameterError, shouldBeObject } from '../../utils' - -export const _request = (options) => { - const name = 'request' - - const isObject = shouldBeObject(options) - if (!isObject.flag) { - const res = { errMsg: `${name}:fail ${isObject.msg}` } - return Promise.reject(res) - } - - const { url, success, fail, complete, method, ...otherOptions } = options as Exclude - if (typeof url !== 'string') { - const res = { - errMsg: getParameterError({ - para: 'url', - correct: 'string', - wrong: url, - }), - } - isFunction(fail) && fail(res) - isFunction(complete) && complete(res) - return Promise.reject(res) - } - - let task!: Taro.RequestTask - const result: ReturnType = new Promise((resolve, reject) => { - const upperMethod = method ? method.toUpperCase() : method - const taskID = native.request({ - url, - method: upperMethod, - ...otherOptions, - success: (res: any) => { - isFunction(success) && success(res) - isFunction(complete) && complete(res) - resolve(res) - }, - fail: (res: any) => { - isFunction(fail) && fail(res) - isFunction(complete) && complete(res) - reject(res) - }, - }) - task = judgeUseAxios ? taskID : NativeRequest.getRequestTask(taskID) - }) as any - - result.onHeadersReceived = task.onHeadersReceived.bind(task) - result.offHeadersReceived = task.offHeadersReceived.bind(task) - result.abort = task.abort.bind(task) - return result -} - -function taroInterceptor (chain) { - return _request(chain.requestParams) -} - -// @ts-ignore -const { Link } = Taro -const link = new Link(taroInterceptor) /** - * 发起 HTTPS 网络请求 - * - * @canUse request - * @__object [url, data, header, timeout, method[OPTIONS, GET, HEAD, POST, PUT, PATCH, DELETE, TRACE, CONNECT], dataType[json, text, base64, arraybuffer], responseType[text, arraybuffer], enableCache] - * @__success [data, header, statusCode, cookies] + * 封装请求方法 + * @param options 请求选项 + * @param useNativeRequest 默认使用true */ -export function request (options) { - const result = link.request.bind(link)(options) - result.catch(() => {}) - return result +export function request(options: any, useNativeRequest: boolean = true){ + return useNativeRequest ? nativeReuqest(options) : h5Request(options); } -/** - * 网络请求任务对象 - * - * @canUse RequestTask - * @__class [abort, onHeadersReceived, offHeadersReceived] - */ - -/** - * 使用拦截器 - * - * @canNotUse addInterceptor - */ -export const addInterceptor = link.addInterceptor.bind(link) -/** - * 清除所有拦截器 - * - * @canNotUse cleanInterceptors - */ -export const cleanInterceptors = link.cleanInterceptors.bind(link) diff --git a/packages/taro-platform-harmony-hybrid/src/api/apis/network/request/nativeRequest.ts b/packages/taro-platform-harmony-hybrid/src/api/apis/network/request/nativeRequest.ts new file mode 100644 index 000000000000..ffbea80fc08a --- /dev/null +++ b/packages/taro-platform-harmony-hybrid/src/api/apis/network/request/nativeRequest.ts @@ -0,0 +1,98 @@ +import Taro from '@tarojs/api' +import { isFunction } from '@tarojs/shared' + +import { NativeRequest } from '../../interface/NativeRequest' +import native, { judgeUseAxios } from '../../NativeApi' +import { getParameterError, shouldBeObject } from '../../utils' + +export const _request = (options) => { + const name = 'request' + + const isObject = shouldBeObject(options) + if (!isObject.flag) { + const res = { errMsg: `${name}:fail ${isObject.msg}` } + return Promise.reject(res) + } + + const { url, success, fail, complete, method, ...otherOptions } = options as Exclude + if (typeof url !== 'string') { + const res = { + errMsg: getParameterError({ + para: 'url', + correct: 'string', + wrong: url, + }), + } + isFunction(fail) && fail(res) + isFunction(complete) && complete(res) + return Promise.reject(res) + } + + let task!: Taro.RequestTask + const result: ReturnType = new Promise((resolve, reject) => { + const upperMethod = method ? method.toUpperCase() : method + const taskID = native.request({ + url, + method: upperMethod, + ...otherOptions, + success: (res: any) => { + isFunction(success) && success(res) + isFunction(complete) && complete(res) + resolve(res) + }, + fail: (res: any) => { + isFunction(fail) && fail(res) + isFunction(complete) && complete(res) + reject(res) + }, + }) + task = judgeUseAxios ? taskID : NativeRequest.getRequestTask(taskID) + }) as any + + result.onHeadersReceived = task.onHeadersReceived.bind(task) + result.offHeadersReceived = task.offHeadersReceived.bind(task) + result.abort = task.abort.bind(task) + return result +} + +function taroInterceptor (chain) { + return _request(chain.requestParams) +} + +// @ts-ignore +const { Link } = Taro +const link = new Link(taroInterceptor) + +/** + * 发起 HTTPS 网络请求 + * + * @canUse request + * @__object [url, data, header, timeout, method[OPTIONS, GET, HEAD, POST, PUT, PATCH, DELETE, TRACE, CONNECT], dataType[json, text, base64, arraybuffer], responseType[text, arraybuffer], enableCache] + * @__success [data, header, statusCode, cookies] + */ +export function request (options) { + const result = link.request.bind(link)(options) + result.catch(() => {}) + return result +} + +/** + * 网络请求任务对象 + * + * @canUse RequestTask + * @__class [abort, onHeadersReceived, offHeadersReceived] + */ + +/** + * 使用拦截器 + * + * @canNotUse addInterceptor + */ +export const addInterceptor = link.addInterceptor.bind(link) + +/** + * 清除所有拦截器 + * + * @canNotUse cleanInterceptors + */ +export const cleanInterceptors = link.cleanInterceptors.bind(link) diff --git a/packages/taro-platform-harmony-hybrid/src/api/apis/osChannelApi.ts b/packages/taro-platform-harmony-hybrid/src/api/apis/osChannelApi.ts index d2de58514f9b..caa6eea322c0 100644 --- a/packages/taro-platform-harmony-hybrid/src/api/apis/osChannelApi.ts +++ b/packages/taro-platform-harmony-hybrid/src/api/apis/osChannelApi.ts @@ -1,4 +1,4 @@ -let http +// let http let display let wifiManager let call @@ -10,7 +10,7 @@ let geoLocationManager try { // @ts-ignore - http = requireNapi('net.http') + // http = requireNapi('net.http') // @ts-ignore display = requireNapi('display') // @ts-ignore @@ -43,181 +43,181 @@ try { }) } catch (e) {} -const errMsgMap = new Map([ - [401, 'Parameter error'], - [201, 'Permission denied'], - [3, 'URL using bad/illegal format or missing URL'], - [7, "Couldn't connect to server"], - [23, 'Failed writing received data to disk/application'], - [25, 'Upload failed'], - [26, 'Failed to open/read local data from file/application'], - [28, 'Timeout was reached'], - [73, 'Remote file already exists'], - [78, 'Remote file not found'], - [999, 'Unknown Other Error'], -]) +// const errMsgMap = new Map([ +// [401, 'Parameter error'], +// [201, 'Permission denied'], +// [3, 'URL using bad/illegal format or missing URL'], +// [7, "Couldn't connect to server"], +// [23, 'Failed writing received data to disk/application'], +// [25, 'Upload failed'], +// [26, 'Failed to open/read local data from file/application'], +// [28, 'Timeout was reached'], +// [73, 'Remote file already exists'], +// [78, 'Remote file not found'], +// [999, 'Unknown Other Error'], +// ]) const ErrorCode = { PARAMETER_ERROR: 202, } -class RequestTask { - private abortFlag: boolean - private readonly fail: (arg0: any) => any - private readonly complete: (arg0: any) => any - private readonly httpRequest: any - private headersCallback: Map - private result: { data?: any, statusCode?: any, header?: any, cookies?: any, errMsg: string | undefined } - private res: { errMsg: string } - - constructor (object: any) { - const { url, header, method = 'GET', timeout, responseType, enableCache } = object || {} - let { data } = object || {} - const { success, fail, complete } = object || {} - this.abortFlag = false - this.fail = fail - this.complete = complete - this.httpRequest = http.createHttp() - this.headersCallback = new Map() - if (!object) { - console.error('[OsChannel] request error: params illegal') - return - } - let isFormUrlEncoded = false - for (const key in header) { - if (key.toLowerCase() === 'content-type') { - if (header[key].toLowerCase().includes('application/x-www-form-urlencoded')) { - isFormUrlEncoded = true - } - break - } - } - - // data为Object类型时,属性的值类型如果是number, request请求时信息会丢失. 故将data转成string类型进行规避 - if (data && (isFormUrlEncoded || ['GET', 'OPTIONS', 'DELETE', 'TRACE', 'CONNECT'].includes(method))) { - const dataArray = [] - for (const key in data) { - // @ts-ignore - dataArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])) - } - data = dataArray.join('&') - } - // header的属性的值类型如果是number, request请求时信息会丢失. 故将各个属性转成string类型 - if (header) { - for (const key in header) { - header[key] = `${header[key]}` - } - } - const httpRequestOptions = { - method: method, - extraData: data || {}, - header: header, - connectTimeout: timeout, - expectDataType: - responseType && responseType === 'arraybuffer' ? http.HttpDataType.ARRAY_BUFFER : http.HttpDataType.STRING, - usingCache: enableCache || false, - } - this.httpRequest - .request(typeof url === 'string' ? url : '', httpRequestOptions) - .then((data) => { - if (success && !this.abortFlag) { - let result = data.result - const { dataType } = object || {} - if (dataType && dataType !== 'json') { - if (typeof data.result === 'object') { - result = JSON.stringify(data.result) - } - } else if (typeof data.result === 'string') { - try { - result = JSON.parse(result) - } catch (err) { - /* empty */ - } - } - const res = { - data: result, - statusCode: data.responseCode, - header: data.header, - cookies: typeof data.cookies === 'string' ? (data.cookies ? [data.cookies] : []) : data.cookies, - errMsg: 'request:ok', - } - this.result = res - success(res) - } - }) - .catch((err: any) => { - console.error('[OsChannel] request error: ' + JSON.stringify(err)) - if (fail && !this.abortFlag) { - const res = { - errMsg: errMsgMap.has(err.code) ? errMsgMap.get(err.code) : 'Unknown Error', - } - this.result = res - fail(res) - } - }) - .finally(() => { - if (complete && !this.abortFlag) { - complete(this.result) - } - }) - } - - /** - * interrupt request task - */ - abort () { - this.httpRequest.destroy() - this.abortFlag = true - this.res = { - errMsg: 'request:fail abort', - } - this.fail && this.fail(this.res) - this.complete && this.complete(this.res) - } - - /** - * subscribe HTTP Response Header event - * @callback params header {Object}: HTTP Response Header - */ - onHeadersReceived (callback: any) { - const taskCallback = (header: any) => { - !this.abortFlag && - callback({ - header, - }) - } - if (!callback) { - console.error('[OsChannel] Invalid, callback is null') - return - } - if (!this.headersCallback.has(callback)) { - this.headersCallback.set(callback, taskCallback) - if (this.httpRequest) { - this.httpRequest.on('headersReceive', taskCallback) - } - } - } - - /** - * unsubscribe HTTP Response Header event - * remove all if callback is null, otherwise remove the specialized callback - */ - offHeadersReceived (callback: any) { - if (!callback) { - this.headersCallback.clear() - if (this.httpRequest) { - this.httpRequest.off('headersReceive') - } - } else if (this.headersCallback.has(callback)) { - if (this.httpRequest) { - this.httpRequest.off('headersReceive', this.headersCallback.get(callback)) - } - this.headersCallback.delete(callback) - } else { - /* empty */ - } - } -} +// class RequestTask { +// private abortFlag: boolean +// private readonly fail: (arg0: any) => any +// private readonly complete: (arg0: any) => any +// private readonly httpRequest: any +// private headersCallback: Map +// private result: { data?: any, statusCode?: any, header?: any, cookies?: any, errMsg: string | undefined } +// private res: { errMsg: string } +// +// constructor (object: any) { +// const { url, header, method = 'GET', timeout, responseType, enableCache } = object || {} +// let { data } = object || {} +// const { success, fail, complete } = object || {} +// this.abortFlag = false +// this.fail = fail +// this.complete = complete +// this.httpRequest = http.createHttp() +// this.headersCallback = new Map() +// if (!object) { +// console.error('[OsChannel] request error: params illegal') +// return +// } +// let isFormUrlEncoded = false +// for (const key in header) { +// if (key.toLowerCase() === 'content-type') { +// if (header[key].toLowerCase().includes('application/x-www-form-urlencoded')) { +// isFormUrlEncoded = true +// } +// break +// } +// } +// +// // data为Object类型时,属性的值类型如果是number, request请求时信息会丢失. 故将data转成string类型进行规避 +// if (data && (isFormUrlEncoded || ['GET', 'OPTIONS', 'DELETE', 'TRACE', 'CONNECT'].includes(method))) { +// const dataArray = [] +// for (const key in data) { +// // @ts-ignore +// dataArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])) +// } +// data = dataArray.join('&') +// } +// // header的属性的值类型如果是number, request请求时信息会丢失. 故将各个属性转成string类型 +// if (header) { +// for (const key in header) { +// header[key] = `${header[key]}` +// } +// } +// const httpRequestOptions = { +// method: method, +// extraData: data || {}, +// header: header, +// connectTimeout: timeout, +// expectDataType: +// responseType && responseType === 'arraybuffer' ? http.HttpDataType.ARRAY_BUFFER : http.HttpDataType.STRING, +// usingCache: enableCache || false, +// } +// this.httpRequest +// .request(typeof url === 'string' ? url : '', httpRequestOptions) +// .then((data) => { +// if (success && !this.abortFlag) { +// let result = data.result +// const { dataType } = object || {} +// if (dataType && dataType !== 'json') { +// if (typeof data.result === 'object') { +// result = JSON.stringify(data.result) +// } +// } else if (typeof data.result === 'string') { +// try { +// result = JSON.parse(result) +// } catch (err) { +// /* empty */ +// } +// } +// const res = { +// data: result, +// statusCode: data.responseCode, +// header: data.header, +// cookies: typeof data.cookies === 'string' ? (data.cookies ? [data.cookies] : []) : data.cookies, +// errMsg: 'request:ok', +// } +// this.result = res +// success(res) +// } +// }) +// .catch((err: any) => { +// console.error('[OsChannel] request error: ' + JSON.stringify(err)) +// if (fail && !this.abortFlag) { +// const res = { +// errMsg: errMsgMap.has(err.code) ? errMsgMap.get(err.code) : 'Unknown Error', +// } +// this.result = res +// fail(res) +// } +// }) +// .finally(() => { +// if (complete && !this.abortFlag) { +// complete(this.result) +// } +// }) +// } +// +// /** +// * interrupt request task +// */ +// abort () { +// this.httpRequest.destroy() +// this.abortFlag = true +// this.res = { +// errMsg: 'request:fail abort', +// } +// this.fail && this.fail(this.res) +// this.complete && this.complete(this.res) +// } +// +// /** +// * subscribe HTTP Response Header event +// * @callback params header {Object}: HTTP Response Header +// */ +// onHeadersReceived (callback: any) { +// const taskCallback = (header: any) => { +// !this.abortFlag && +// callback({ +// header, +// }) +// } +// if (!callback) { +// console.error('[OsChannel] Invalid, callback is null') +// return +// } +// if (!this.headersCallback.has(callback)) { +// this.headersCallback.set(callback, taskCallback) +// if (this.httpRequest) { +// this.httpRequest.on('headersReceive', taskCallback) +// } +// } +// } +// +// /** +// * unsubscribe HTTP Response Header event +// * remove all if callback is null, otherwise remove the specialized callback +// */ +// offHeadersReceived (callback: any) { +// if (!callback) { +// this.headersCallback.clear() +// if (this.httpRequest) { +// this.httpRequest.off('headersReceive') +// } +// } else if (this.headersCallback.has(callback)) { +// if (this.httpRequest) { +// this.httpRequest.off('headersReceive', this.headersCallback.get(callback)) +// } +// this.headersCallback.delete(callback) +// } else { +// /* empty */ +// } +// } +// } const hideKeyboard = () => { return new Promise((resolve, reject) => { @@ -372,26 +372,26 @@ const getAppAuthorizeSetting = () => { return result } -const request = (options: any) => { - const { success, fail, complete } = options - const task = new RequestTask(options) - // if success / fail / complete, return requestTask otherwise return Promise - if (options && !success && !fail && !complete) { - success(task) - return - } - if (!options) { - fail(['illegal params', -1]) - } - return task -} +// const request = (options: any) => { +// const { success, fail, complete } = options +// const task = new RequestTask(options) +// // if success / fail / complete, return requestTask otherwise return Promise +// if (options && !success && !fail && !complete) { +// success(task) +// return +// } +// if (!options) { +// fail(['illegal params', -1]) +// } +// return task +// } const osChannelApi = { getSystemSetting, hideKeyboard, makePhoneCall, getAppAuthorizeSetting, - request, + // request, } export default osChannelApi