UNPKG

house-middleware-sdk

Version:

58 hosue rn native sdk

616 lines (564 loc) 21.2 kB
import md5 from 'md5'; import { initNativeParams } from '../sdk/getNativeParams'; import { isString } from './typeUtils' import { writeLog } from '../sdk/actionLog'; import { NativeModules, Platform } from 'react-native'; const defaultUniqueIdentifie = 'defaultUniqueIdentifie'; const reqTypeGet = 'GET'; const reqTypePost = 'POST'; let reqCurrentTime = {}; const maxTime = 20000; const guardMaxTime = maxTime + 2000; const slowMaxTime = 500; const rn_response_slow = 'rn_response_slow'; const NoNeedUpLoadError = true;//网络上报dev开关 /* 获取当前时间精确到毫秒 */ const getCurrentTime = () => { return (new Date()).getTime(); }; const status = (response) => { if (response.status >= 200 && response.status < 300) { return Promise.resolve(response); } else { //上报解析失败 let uniqueIdentifier = response.url; getPublicParamsAndHeader() .then((initParams) => { let postDict = { jumpParams: initParams.jumpParams, url: uniqueIdentifier, params: {}, errorDict: { message: isString(response.message) ? response.message : '', stack: isString(response.stack) ? response.stack : '', _bodyText: isString(response._bodyText) ? response._bodyText : '', } }; uploadErrorLog(uniqueIdentifier, postDict); }).catch((error) => { }); return Promise.reject(new Error(response.statusText)); } }; const error = (error) => { return Promise.reject(error); }; const toJson = (response) => { return new Promise((resolve, reject) => { response.json().then((jsonData) => { resolve(jsonData); //超时上报 let uniqueIdentifier = response.url; let recordMsg = reqCurrentTime[uniqueIdentifier]; if (recordMsg) { let duration = getCurrentTime() - recordMsg.time; if (duration > slowMaxTime) { getPublicParamsAndHeader() .then((initParams) => { let postDict = { duration: duration, jumpParams: initParams.jumpParams, url: uniqueIdentifier, params: {}, errorDict: { message: "接口响应过慢" } }; uploadErrorLog(uniqueIdentifier, postDict, rn_response_slow); }).catch((error) => { }); } else { delete reqCurrentTime[uniqueIdentifier];//解析成功则主动删除记录 } } }).catch((error) => { reject(error); //上报解析失败 let uniqueIdentifier = response.url; getPublicParamsAndHeader() .then((initParams) => { let postDict = { jumpParams: initParams.jumpParams, url: uniqueIdentifier, params: {}, errorDict: { message: isString(error.message) ? error.message : '', stack: isString(error.stack) ? error.stack : '', _bodyText: isString(response._bodyText) ? response._bodyText : '', } }; uploadErrorLog(uniqueIdentifier, postDict); }).catch((error) => { }); }); }); } const timeout = (url, formData, params) => { return new Promise((resolve, reject) => setTimeout(() => { reject('网络超时'); //上报超时 getPublicParamsAndHeader() .then((initParams) => { let uniqueIdentifier = jointReqUrl(url, params, formData, initParams); if (!reqCurrentTime[uniqueIdentifier]) return; let postDict = { jumpParams: initParams.jumpParams, url: url, params: params, errorDict: { message: '网络超时', } }; uploadErrorLog(uniqueIdentifier, postDict); }); }, maxTime)); }; const getPublicParamsAndHeader = () => new Promise((resolve) => { initNativeParams((initParams) => { if (!initParams.publicParams) initParams.publicParams = {}; resolve(initParams); }, true); }); const doGetRequest = (url, params, formData, initParams) => { if (global.SCENE == 'roomer') { // get请求次数埋点 writeLog( 'new_other', { wb: '200000003430000100000010', ajk: '1101400028' }, '1', { url: url, bundleversion: global.__WB_MAIN_BUNDLE_VER__ } ); require("house-middleware-sdk/utils/findImpl").default(() => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.58.get.请求次数.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.anjuke.get.请求次数.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`58同镇.get.请求次数.${global.__WB_MAIN_BUNDLE_VER__}`)); }); if (initParams.httpHeader && initParams.httpHeader instanceof Object) { var keysArr = Object.keys(initParams.httpHeader); if (keysArr.length == 0) { // header空埋点 writeLog( 'new_other', { wb: '200000003704000100000010', ajk: '1101400205' }, '1', { error: JSON.stringify(initParams.httpHeader), type: 'GET head keysArr 0 after' } ); require("house-middleware-sdk/utils/findImpl").default(() => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.58.get.header空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.anjuke.get.header空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`58同镇.get.header空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }); } } if (initParams.jumpParams.content.params && !initParams.jumpParams.content.params.bundleid) { // 协议空埋点 writeLog( 'new_other', { wb: '200000003705000100000010', ajk: '1101400206' }, '1', { error: 'GET jump keysArr 0 after' } ); require("house-middleware-sdk/utils/findImpl").default(() => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.58.get.协议空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.anjuke.get.协议空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`58同镇.get.协议空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }); } } let getReqUrl = jointReqUrl(url, params, formData, initParams); let uniqueIdentifier = getReqUrl; reqCurrentTime[uniqueIdentifier] = { time: getCurrentTime(), headers: initParams.httpHeader }; return fetch(getReqUrl, { method: 'GET', headers: initParams.httpHeader }); }; const doPostRequest = (url, params, formData, initParams) => { if (global.SCENE == 'roomer') { writeLog( 'new_other', { wb: '200000003430000100000010', ajk: '1101400028' }, '1', { url: url, bundleversion: global.__WB_MAIN_BUNDLE_VER__ } ); require("house-middleware-sdk/utils/findImpl").default(() => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.58.post.请求次数.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.anjuke.post.请求次数.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`58同镇..post.请求次数.${global.__WB_MAIN_BUNDLE_VER__}`)); }); if (initParams.httpHeader && initParams.httpHeader instanceof Object) { var keysArr = Object.keys(initParams.httpHeader); if (keysArr.length == 0) { // header空埋点 writeLog( 'new_other', { wb: '200000003704000100000010', ajk: '1101400205' }, '1', { error: JSON.stringify(initParams.httpHeader), type: 'POST head keysArr 0 after' } ); require("house-middleware-sdk/utils/findImpl").default(() => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.58.post.header空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.anjuke.post.header空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`58同镇..post.header空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }); } } if (initParams.jumpParams.content.params && !initParams.jumpParams.content.params.bundleid) { // 协议空埋点 writeLog( 'new_other', { wb: '200000003705000100000010', ajk: '1101400206' }, '1', { error: 'POST jump keysArr 0 after' } ); require("house-middleware-sdk/utils/findImpl").default(() => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.58.post.协议空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`找室友.anjuke.post.协议空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }, () => { }, () => { require("@w/wbapp/src/sdk/jscout").jscout(new Error(`58同镇..post.协议空埋点.${global.__WB_MAIN_BUNDLE_VER__}`)); }); } } let postReqUrl = jointReqUrl(url, params, formData, initParams); let uniqueIdentifier = postReqUrl; reqCurrentTime[uniqueIdentifier] = { time: getCurrentTime(), headers: initParams.httpHeader }; return fetch(postReqUrl, { method: 'POST', headers: initParams.httpHeader, body: formData }); }; const jointReqUrl = (url, params, formData, initParams) => { let extId = { extId: createSignature(defaultUniqueIdentifie, formData) }; if (NoNeedUpLoadError) { //dev阶段删除由于不上报,所以删除extTime信息 delete params.extTime; extId = {}; } return buildRequestURL(url, Object.assign(initParams.publicParams, params, extId)); }; function get(url, params) { !url && console.error('url异常'); if (!params) params = {}; return new Promise((resolve, reject) => { require("../utils/findImpl").default(() => { getWbAJKImpl(url, params).then(res => { resolve(res); }).catch(error => { reject(error); }); }, () => { getWbAJKImpl(url, params).then(res => { resolve(res); }).catch(error => { reject(error); }); }, () => { getYdjjrImpl(url, params).then(res => { resolve(res); }).catch(error => { reject(error); }); }, () => { getWbtzImpl(url, params).then(res => { resolve(res); }).catch(error => { reject(error); }); }) }) } function getWbAJKImpl(url, params) { //添加时间戳确保唯一性 params.extTime = getCurrentTime(); let formData = null; return new Promise.race([ getPublicParamsAndHeader() .then((initParams) => doGetRequest(url, params, formData, initParams)) .then(status) .then(toJson) .catch(error), timeout(url, formData, params) ]); } function ydjjrStatus(response, resolve, reject) { if (Platform.OS === 'ios') { // ios直接返回业务对象 resolve(response) } else { if ((response.status >= 200 && response.status < 300) || response.status === 304) { if (response.status !== 204) { resolve(response.json()) } else { resolve() } // console.log('[AjaxSuccess]', response.status, response.url) } else { // console.log('[AjaxError]', response.status, response.url) response .json() .then((oData) => { oData.codeStatus = response.status return oData }) .then(reject) } } } function getYdjjrImpl(url, params) { if (Platform.OS === 'ios') { // @ts-ignore fetch = NativeModules.BrokerFetch.fetch } return new Promise((resolve, reject) => { fetch(buildRequestURL(url, params || {}), { method: 'GET', }) .then((response) => { ydjjrStatus(response, resolve, reject) }) .catch((error) => { reject(error) }) }) } //TODO:{58同镇 get...} function getWbtzImpl(url, params) { //添加时间戳确保唯一性 params.extTime = getCurrentTime(); let formData = null; return new Promise.race([ getPublicParamsAndHeader() .then((initParams) => doGetRequest(url, params, formData, initParams)) .then(status) .then(toJson) .catch(error), timeout(url, formData, params) ]); } function post(url, formData, params) { !url && console.error('url异常'); if (!params) params = {}; return new Promise((resolve, reject) => { require("../utils/findImpl") .default( () => { postWbAjkImpl(url, formData, params).then(res => { resolve(res); }).catch(error => { reject(error); }) }, () => { postWbAjkImpl(url, formData, params).then(res => { resolve(res); }).catch(error => { reject(error); }) }, () => { postYdjjrImpl(url, formData, params).then(res => { resolve(res); }).catch(error => { reject(error); }) }, () => { postWbtzImpl(url, formData, params).then(res => { resolve(res); }).catch(error => { reject(error); }) }) }) } function postWbAjkImpl(url, formData, params) { //添加时间戳确保唯一性 params.extTime = getCurrentTime(); return new Promise.race([ getPublicParamsAndHeader() .then((initParams) => doPostRequest(url, params, formData, initParams)) .then(status) .then(toJson) .catch(error), timeout(url, formData, params) ]); } function postYdjjrImpl(url, formData, params) { if (Platform.OS === 'ios') { // @ts-ignore fetch = NativeModules.BrokerFetch.fetch } return new Promise((resolve, reject) => { fetch(buildRequestURL(url, params || {}), { method: 'POST', body: typeof formData === 'string' ? formData : JSON.stringify(formData), headers: { Accept: 'application/json', 'Content-Type': 'application/json', } }) .then((response) => { ydjjrStatus(response, resolve, reject) }) .catch((error) => { reject(error) }) }) } //TODO:{58同镇 post...} function postWbtzImpl(url, formData, params) { //添加时间戳确保唯一性 params.extTime = getCurrentTime(); return new Promise.race([ getPublicParamsAndHeader() .then((initParams) => doPostRequest(url, params, formData, initParams)) .then(status) .then(toJson) .catch(error), timeout(url, formData, params) ]); } function buildRequestURL(requestUrl, params) { if (params && Object.keys(params).length > 0) { const queryString = Object.keys(params) .map(key => `${key}=${encodeURIComponent(params[key])}`) .join('&'); if (requestUrl.indexOf('?') == -1) { //没有 return `${requestUrl}?${queryString}`; } else if (requestUrl.indexOf('?') == requestUrl.length - 1) { //类似这种 //https://www.hao123.com? return `${requestUrl}${queryString}`; } else { return `${requestUrl}&${queryString}`; } } else { return requestUrl; } } function createSignature(postfix, params) { if (params) { let data = {}; if (params instanceof FormData) { params.getParts() .map((v) => { data[String(v.fieldName)] = v.string; }); } else { data = params; } const sortParamsObj = Object.keys(data) .sort(); const sortParamsString = Object.keys(sortParamsObj) .map(key => `${sortParamsObj[key]}=${data[sortParamsObj[key]]}`) .join('&'); const signature = `${sortParamsString}&${postfix}`; return md5(signature); } else { return md5(postfix); } } function uploadErrorLog(uniqueIdentifier, errorObj, type = 'rn_error') { if (NoNeedUpLoadError) { console.warn('uploadError:', errorObj); return; } if (typeof type !== "string") { console.warn('The "type" must be a string'); return; } let recordMsg = reqCurrentTime[uniqueIdentifier]; if (!recordMsg) return; let duration = getCurrentTime() - recordMsg.time; let commonParams = { headers: recordMsg.headers, duration: Math.min(isNaN(duration) ? maxTime : duration, maxTime), }; delete reqCurrentTime[uniqueIdentifier];//发送后删除记录 let postUrl = 'https://flog.58.com/error'; fetch(postUrl, { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, method: 'POST', body: JSON.stringify({ "type": type, "rn_error_data": Object.assign(commonParams, errorObj) }) }).then((response) => { }).catch((error) => { }); } //维护时间记录池 (function guardTimePool() { setInterval(() => { Object.keys(reqCurrentTime).map((key) => { let recordMsg = reqCurrentTime[key]; if (recordMsg && (getCurrentTime() - recordMsg.time > guardMaxTime)) { // console.warn('delete:' + key); delete reqCurrentTime[key]; } }); }, guardMaxTime); })(); export { get, post, buildRequestURL, createSignature }; // function buildBody(pageIndex, pageTimeKey) { // const formData = new FormData(); // formData.append('page', pageIndex); // formData.append('cityId', global.httpHeader.cid); // formData.append('localName', global.httpHeader.dirname); // formData.append('newVersion', Constants.VERSION); // formData.append('skipId', pageTimeKey); // return formData; // }