house-middleware-sdk
Version:
58 hosue rn native sdk
616 lines (564 loc) • 21.2 kB
JavaScript
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;
// }