1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| function fetchHandler() { const self = this; if (!("Proxy" in window)) return;
const textTypes = new Set([ "image/svg", "application/xml", "application/xhtml", "application/html", ]); const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i; const nullBodyResponses = new Set([101, 204, 205, 304]); function detectResponseType(_contentType = "") { if (!_contentType) { return "json"; } const contentType = _contentType.split(";").shift() || ""; if (JSON_RE.test(contentType)) { return "json"; } if (textTypes.has(contentType) || contentType.startsWith("text/")) { return "text"; } return "blob"; }
window.fetch = new Proxy(window.fetch, { apply(target, thisArg, args) { let _context = null; let req = null; const startTime = new Date(); try { req = new Request(...args); const urlObj = self._resolveUrl(req.url); let pathname = urlObj.pathname || ""; if (pathname[0] !== "/") { pathname = "/" + pathname; } let reqBody = args[1]?.body || ""; if (reqBody instanceof Blob) { reqBody = "Blob:" + reqBody.type; } else if (typeof reqBody === "object") { try { reqBody = JSON.stringify(reqBody); } catch (e) { reqBody = "unknown object"; } } if (typeof reqBody !== "string") { reqBody = "unknown"; }
_context = { requestContext: { host: urlObj.host, pathname, query: urlObj.search, method: req.method, body: reqBody, }, }; } catch (e) {} const fetchInstance = target.apply(thisArg, args);
if (req && _context) { fetchInstance .then((response) => { const endTime = new Date();
const costTime = (endTime - startTime) / 1000; const resType = detectResponseType( response.headers.get("content-type") || "" ); const _readBody = response.body && !nullBodyResponses.has(response.status) && (args[1]?.responseType === "json" || resType === "json" || resType === "text") ? response.clone().text() : Promise.resolve("unknown"); _readBody.then((resBody) => { if (_context) { Object.assign(_context.requestContext, { statusCode: response.status || 200, responseTime: costTime, responseText: resBody, }); } }); }) .catch((error) => { const endTime = new Date(); const costTime = (endTime - startTime) / 1000; Object.assign(_context.requestContext, { responseTime: costTime, responseText: (error.message || "") + (error.stack || ""), }); throw error; }); } return fetchInstance; }, }); }
|