GM Fetch

A fetch API of GM_xmlhttpRequest

目前为 2023-08-02 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/472236/1229371/GM%20Fetch.js

// ==UserScript==
// @name         GM Fetch
// @namespace    https://github.com/Sec-ant/gm-fetch
// @version      0.0.6
// @author       Ze-Zheng Wu
// @description  A fetch API of 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.git
// @supportURL   https://github.com/Sec-ant/gm-fetch/issues
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function () {
  'use strict';

  (function(global, factory) {
    typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.gmFetch = factory());
  })(globalThis, function() {
    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;
        var parts = line.split(":");
        var key = (_a = parts.shift()) == null ? void 0 : _a.trim();
        if (key) {
          var 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 request = new Request(input, init);
      if (request.signal.aborted) {
        throw new DOMException("Request is aborted", "AbortError");
      }
      const data = await request.blob();
      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 } = _GM_xmlhttpRequest({
            method: request.method.toUpperCase(),
            url: request.url || location.href,
            headers,
            data: data.size ? data : void 0,
            redirect: request.redirect,
            binary: true,
            nocache: request.cache === "no-store",
            revalidate: request.cache === "reload",
            timeout: 3e5,
            responseType: _GM_xmlhttpRequest.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,
                {
                  headers: parseHeaders(responseHeaders),
                  status,
                  statusText
                }
              );
              Object.defineProperties(response, {
                url: {
                  value: finalUrl
                },
                redirected: {
                  value: request.url !== finalUrl
                },
                type: {
                  value: "basic"
                }
              });
              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("Aborted", "AbortError"));
              resolveBlob(null);
            }
          });
          request.signal.addEventListener("abort", abort);
        });
      });
    };
    return gmFetch;
  });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址