您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
A fetch API for GM_xmlhttpRequest / GM.xmlHttpRequest
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/472236/1239303/GM%20Fetch.js
// ==UserScript== // @name GM Fetch // @namespace https://github.com/Sec-ant/gm-fetch // @version 1.0.0 // @author Ze-Zheng Wu // @description A fetch API for GM_xmlhttpRequest / GM.xmlHttpRequest // @license MIT // @homepage https://github.com/Sec-ant/gm-fetch // @homepageURL https://github.com/Sec-ant/gm-fetch // @source https://github.com/Sec-ant/gm-fetch // @supportURL https://github.com/Sec-ant/gm-fetch/issues // @match *://*/* // @grant GM.xmlHttpRequest // @grant GM_xmlhttpRequest // ==/UserScript== (function () { 'use strict'; (function(global, factory) { (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.gmFetch = factory()); })(globalThis, function() { var _GM = /* @__PURE__ */ (() => typeof GM != "undefined" ? GM : void 0)(); var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)(); function parseHeaders(rawHeaders) { const headers = new Headers(); const preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, " "); preProcessedHeaders.split(/\r?\n/).forEach(function(line) { var _a; const parts = line.split(":"); const key = (_a = parts.shift()) == null ? void 0 : _a.trim(); if (key) { const value = parts.join(":").trim(); try { headers.append(key, value); } catch (error) { console.warn("Response " + error.message); } } }); return headers; } const gmFetch = async function(input, init) { const gmXhr = _GM_xmlhttpRequest || _GM.xmlHttpRequest; if (typeof gmXhr !== "function") { throw new DOMException( "GM_xmlhttpRequest or GM.xmlHttpRequest is not granted.", "NotFoundError" ); } const request = new Request(input, init); if (request.signal.aborted) { throw new DOMException("Network request aborted.", "AbortError"); } const dataBuffer = await request.arrayBuffer(); const data = dataBuffer.byteLength ? new TextDecoder().decode(dataBuffer) : void 0; const headers = Object.fromEntries(request.headers); new Headers(init == null ? void 0 : init.headers).forEach((value, key) => { headers[key] = value; }); return new Promise((resolve, reject) => { let settled = false; const responseBlobPromise = new Promise((resolveBlob) => { const { abort } = gmXhr({ method: request.method.toUpperCase(), url: request.url || location.href, headers, data, redirect: request.redirect, binary: true, nocache: request.cache === "no-store", revalidate: request.cache === "reload", timeout: 3e5, responseType: gmXhr.RESPONSE_TYPE_STREAM ?? "blob", overrideMimeType: request.headers.get("Content-Type") ?? void 0, anonymous: request.credentials === "omit", onload: ({ response: responseBody }) => { if (settled) { resolveBlob(null); return; } resolveBlob(responseBody); }, async onreadystatechange({ readyState, responseHeaders, status, statusText, finalUrl, response: responseBody }) { if (readyState === XMLHttpRequest.DONE) { request.signal.removeEventListener("abort", abort); } else if (readyState !== XMLHttpRequest.HEADERS_RECEIVED) { return; } if (settled) { resolveBlob(null); return; } const response = new Response( responseBody instanceof ReadableStream ? responseBody : await responseBlobPromise, { status, statusText } ); Object.defineProperties(response, { url: { value: finalUrl }, redirected: { value: request.url !== finalUrl }, type: { value: "basic" }, headers: { value: parseHeaders(responseHeaders) } }); resolve(response); settled = true; }, onerror: ({ statusText, error }) => { reject( new TypeError(statusText || error || "Network request failed.") ); resolveBlob(null); }, ontimeout() { reject(new TypeError("Network request timeout.")); resolveBlob(null); }, onabort() { reject(new DOMException("Network request aborted.", "AbortError")); resolveBlob(null); } }); request.signal.addEventListener("abort", abort); }); }); }; return gmFetch; }); })();