您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Useful library for sending requests.
当前为
此脚本不应直接安装,它是供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/405822/820080/Monkey%20Requests.js
// ==UserScript== // @name Monkey Requests // @namespace https://rafaelgssa.gitlab.io/monkey-scripts // @version 1.1.3 // @author rafaelgssa // @description Useful library for sending requests. // @match *://*/* // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js // @require https://gf.qytechs.cn/scripts/405802-monkey-dom/code/Monkey%20DOM.js // @require https://gf.qytechs.cn/scripts/405813-monkey-utils/code/Monkey%20Utils.js // @grant GM.xmlHttpRequest // @grant GM_xmlhttpRequest // ==/UserScript== /* global MonkeyDom, MonkeyUtils */ /** * @typedef {'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE'} RequestMethod * @typedef {Object} MonkeyResponse * @property {string} url * @property {string} text * @property {Object} [json] * @property {Document} [dom] * @typedef {{ [K in RequestMethod]: (url: string, options?: RequestInit | GM.Request) => Promise<MonkeyResponse> }} ShorthandSend */ // eslint-disable-next-line const MonkeyRequests = (() => { /** @type {RequestMethod[]} */ const methods = ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE']; /** * @param {RequestMethod} method * @param {string} url * @param {RequestInit | GM.Request} [options] * @returns {Promise<MonkeyResponse>} */ const _sendWithMethod = (method, url, options = {}) => { return send(url, { ...options, method }); }; /** * @param {string} url * @param {RequestInit | GM.Request} [options] * @returns {Promise<MonkeyResponse>} */ const send = (url, options = {}) => { if (_isInternal(url, options)) { return _sendInternal(url, options); } return _sendExternal(url, options); }; /** * Checks if the request is internal (uses window.fetch) or external (uses GM.xmlHttpRequest to bypass CORS). * @param {string} url * @param {RequestInit | GM.Request} options * @returns {options is RequestInit} */ // eslint-disable-next-line const _isInternal = (url, options) => { return url.includes(window.location.host); }; /** * @param {string} url * @param {RequestInit} options * @returns {Promise<MonkeyResponse>} */ const _sendInternal = async (url, options) => { const [internalFetch, internalOptions] = _getInternalObjects(options); const fetchResponse = await internalFetch(url, internalOptions); /** @type {MonkeyResponse} */ const response = { url: fetchResponse.url, text: await fetchResponse.text(), }; return _processResponse(response); }; /** * Allows the request to be made in the current Firefox container. * @param {RequestInit} options * @returns {[Function, RequestInit]} */ const _getInternalObjects = (options) => { if ('wrappedJSObject' in window) { window.wrappedJSObject.options = cloneInto(options, window); return [window.wrappedJSObject.fetch, window.wrappedJSObject.options]; } return [window.fetch, options]; }; /** * @param {string} url * @param {Partial<GM.Request>} options * @returns {Promise<MonkeyResponse>} */ const _sendExternal = (url, options) => { return new Promise((resolve) => { GM.xmlHttpRequest({ url, method: 'GET', ...options, onload: (gmResponse) => { /** @type {MonkeyResponse} */ const response = { url: gmResponse.finalUrl, text: gmResponse.responseText, }; resolve(_processResponse(response)); }, }); }); }; /** * @param {MonkeyResponse} response * @returns {MonkeyResponse} */ const _processResponse = (response) => { const processedResponse = { ...response }; try { processedResponse.dom = MonkeyDom.parse(response.text); } catch (err) { // Response is not a DOM, just ignore. } try { processedResponse.json = JSON.parse(response.text); } catch (err) { // Response is not a JSON, just ignore. } return processedResponse; }; /** * Parses a query string into an object. * @param {string} query The query to parse. * @returns {Record<string, string>} The parsed object. */ const parseQuery = (query) => { /** @type {Record<string, string>} */ const params = {}; const rawQuery = query.startsWith('?') ? query.slice(1) : query; const parts = rawQuery.split('&').filter(MonkeyUtils.isSet); for (const part of parts) { const [key, value] = part.split('=').filter(MonkeyUtils.isSet); params[key] = value; } return params; }; /** * Converts an object to a query string. * @param {Record<string, unknown>} obj The object to convert. * @returns {string} The converted query string, without '?'. */ const convertToQuery = (obj) => { return Object.entries(obj) .map((entry) => entry.join('=')) .join('&'); }; const shorthandSend = /** @type {ShorthandSend} */ ({}); for (const method of methods) { shorthandSend[method] = _sendWithMethod.bind(null, method); } return { ...shorthandSend, parseQuery, convertToQuery, send, }; })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址