import { isExt, isGm } from "./browser"; import { sendMsg } from "./msg"; import { MSG_FETCH, CACHE_NAME, OPT_TRANS_MICROSOFT, OPT_TRANS_OPENAI, } from "../config"; /** * 油猴脚本的请求封装 * @param {*} input * @param {*} init * @returns */ const fetchGM = async (input, { method, headers, body }) => new Promise((resolve, reject) => { try { window.GM.xmlhttpRequest({ method, url: input, headers, data: body, onload: (response) => { resolve(new Response(response.response)); }, onerror: (error) => { reject(error); }, }); } catch (error) { reject(error); } }); /** * 构造缓存 request * @param {*} request * @returns */ const newCacheReq = async (request, translator) => { if (translator === OPT_TRANS_MICROSOFT) { request.headers.delete("Authorization"); } else if (translator === OPT_TRANS_OPENAI) { request.headers.delete("Authorization"); request.headers.delete("api-key"); } if (request.method !== "GET") { const body = await request.text(); const cacheUrl = new URL(request.url); cacheUrl.pathname += body; request = new Request(cacheUrl.toString(), { method: "GET" }); } return request; }; /** * 请求数据 * @param {*} input * @param {*} init * @param {*} opts * @returns */ export const fetchData = async (input, init, { useCache, translator } = {}) => { const cacheReq = await newCacheReq(new Request(input, init), translator); const cache = await caches.open(CACHE_NAME); let res; // 查询缓存 if (useCache) { try { res = await cache.match(cacheReq); } catch (err) { console.log("[cache match]", err); } } // 发送请求 if (!res) { if (isGm) { res = await fetchGM(input, init); } else { res = await fetch(input, init); } } if (!res?.ok) { throw new Error(`response: ${res.statusText}`); } // 插入缓存 if (useCache) { try { await cache.put(cacheReq, res.clone()); } catch (err) { console.log("[cache put]", err); } } const contentType = res.headers.get("Content-Type"); if (contentType?.includes("json")) { return await res.json(); } return await res.text(); }; /** * fetch 兼容性封装 * @param {*} input * @param {*} init * @param {*} opts * @returns */ export const fetchPolyfill = async (input, init, opts) => { // 插件 if (isExt) { const res = await sendMsg(MSG_FETCH, { input, init, opts }); if (res.error) { throw new Error(res.error); } return res.data; } // 油猴/网页 return await fetchData(input, init, opts); };