fet-block
Version:
fetBlock is a web h5 request hook library
122 lines (110 loc) • 3.68 kB
JavaScript
/*!
* fet-block v1.0.0
* (c) sheldon cui
* Released under the MIT License.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.fetBlock = {}));
})(this, (function (exports) { 'use strict';
// 技巧:自杀式函数状态记录。
let getPrototypeOf = function (obj) {
if (Object.setPrototypeOf) {
getPrototypeOf = Object.getPrototypeOf;
} else {
getPrototypeOf = function (obj) {
return obj.__proto__;
};
}
return getPrototypeOf(obj);
};
function getNativeXhr() {
let xhrProto = window.XMLHttpRequest.prototype;
while (xhrProto && getPrototypeOf(xhrProto) !== XMLHttpRequestEventTarget.prototype) {
xhrProto = getPrototypeOf(xhrProto);
}
return xhrProto.constructor;
}
const nativeXMLHttpRequest = getNativeXhr();
// 使用原生
async function nativeXhrRequest(options) {
return new Promise(resolve => {
const xhr = new nativeXMLHttpRequest();
xhr.openUrl = options.url;
xhr.open(options.method || 'get', options.url);
xhr.timeout = options.timeout || 5000;
xhr.responseType = options.responseType || 'text';
xhr.onload = function () {
if (xhr.responseType === 'text') {
resolve({
status: xhr.status,
statusText: xhr.statusText,
body: xhr.responseText,
headers: xhr.getAllResponseHeaders()
});
} else {
resolve(xhr.response);
}
};
xhr.onerror = function (e) {
reject(new Error('network error'));
};
xhr.ontimeout = function (e) {
reject(new Error('network timeout'));
};
xhr.send();
});
}
// 执行script脚本
function execScript(scriptContent) {
const ele = document.createElement('script');
ele.innerHTML = scriptContent;
document.body.appendChild(ele);
document.body.removeChild(ele);
}
function getAllUrlParams(url) {
const queryStr = url.split('#')[0].split('?')[1] || '';
const obj = {};
queryStr.split('&').forEach(item => {
const [key, value] = item.split('=');
obj[key] = value;
});
return obj;
}
function getUrlParams(url, name) {
return getAllUrlParams(url)[name];
}
function printDebugLog(...args) {
const isDebug = getUrlParams(window.location.href, 'fetblock_debug');
if (isDebug) {
console.warn(...args);
}
}
const logicUrl = {
prod: `https://www.unpkg.com/fet@${"1.0.0"}/umd/fetBlockLogic.min.js`,
dev: `/dist/fetBlockLogic@${"1.0.0"}.umd.js`
}["prod"];
const LOCAL_STORAGE_FET_BLOCK_LOGIC_KEY = 'fet_block_logic_js_content';
async function init(options = {}) {
printDebugLog('stub exec', logicUrl);
if (options.configUrl) {
window.fetBlockConfigUrl = configUrl;
}
// 1. 读取本地配置并执行
const logicContentFromLocal = localStorage.getItem(LOCAL_STORAGE_FET_BLOCK_LOGIC_KEY);
if (logicContentFromLocal && logicContentFromLocal.includes('fetBlock')) {
execScript(logicContentFromLocal);
}
// 2. 异步拉取远程配置
const logicContent = await nativeXhrRequest({
url: logicUrl,
method: 'get'
});
localStorage.setItem(LOCAL_STORAGE_FET_BLOCK_LOGIC_KEY, logicContent?.body);
if (!logicContentFromLocal && logicContent?.body && logicContent?.body.includes('fetBlock')) {
execScript(logicContent?.body);
}
}
exports.init = init;
}));