您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Initiate an XHR request on the page
当前为
- // ==UserScript==
- // @name http-on-pages
- // @namespace https://github.com/pansong291/
- // @version 0.1.6
- // @description Initiate an XHR request on the page
- // @description:zh 在页面上发起 XHR 请求
- // @author paso
- // @license Apache-2.0
- // @match *://*/*
- // @grant none
- // @noframes
- // @run-at context-menu
- // @require https://update.greasyfork.org/scripts/473443/1368763/popup-inject.js
- // ==/UserScript==
- ;(function () {
- 'use strict'
- const namespace = 'paso-http-on-pages'
- window.paso.injectPopup({
- namespace,
- actionName: 'Http Request',
- collapse: '70%',
- content: `
- <div class="tip-box info monospace">const data = { headers: {}, params: {}, body: void 0, withCredentials: true }</div>
- <div class="flex gap-4" style="flex-direction: row;align-items: flex-start;">
- <select id="${namespace}-http-method" class="input"></select>
- <input type="text" id="${namespace}-ipt-url" class="monospace input" autocomplete="off">
- <button type="button" id="${namespace}-btn-submit" class="button">Submit</button>
- </div>
- <div id="${namespace}-error-tip-box" class="monospace"></div>
- <textarea id="${namespace}-ipt-data" class="monospace input" spellcheck="false"></textarea>`,
- style: `
- <style>
- .popup {
- gap: 4px;
- }
- .gap-4 {
- gap: 4px;
- }
- .tip-box.info {
- background: #d3dff7;
- border-left: 6px solid #3d7fff;
- border-radius: 4px;
- padding: 16px;
- }
- #${namespace}-http-method {
- width: 90px;
- }
- #${namespace}-ipt-url {
- flex: 1 0 300px;
- }
- #${namespace}-btn-submit {
- width: 100px;
- }
- #${namespace}-ipt-data {
- height: 400px;
- }
- #${namespace}-error-tip-box {
- background: #fdd;
- border-left: 6px solid #f66;
- border-radius: 4px;
- padding: 16px;
- }
- #${namespace}-error-tip-box:empty {
- display: none;
- }
- </style>`
- }).then((result) => {
- const { popup } = result.elem
- const sel_http_method = popup.querySelector(`#${namespace}-http-method`)
- const ipt_url = popup.querySelector(`#${namespace}-ipt-url`)
- const ipt_data = popup.querySelector(`#${namespace}-ipt-data`)
- const btn_submit = popup.querySelector(`#${namespace}-btn-submit`)
- const error_tip = popup.querySelector(`#${namespace}-error-tip-box`)
- const method_options = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH']
- sel_http_method.innerHTML = method_options.map(op => `<option value="${op}">${op}</option>`).join('')
- const cache = getCache()
- if (cache) {
- if (cache.method) sel_http_method.value = cache.method
- if (cache.url) ipt_url.value = cache.url
- if (cache.data) ipt_data.value = cache.data
- }
- btn_submit.onclick = tryTo(() => {
- const method = sel_http_method.value
- const url = ipt_url.value
- const dataCode = ipt_data.value
- if (!url) throw 'Url is required'
- const isGet = method === 'GET'
- const data = {
- headers: { 'Content-Type': isGet ? 'application/x-www-form-urlencoded' : 'application/json' },
- params: {},
- body: void 0,
- withCredentials: true
- }
- const handleData = new Function('data', dataCode)
- handleData.call(data, data)
- const request = new XMLHttpRequest()
- request.open(method, url + serializeQueryParam(data.params))
- request.withCredentials = !!data.withCredentials
- Object.entries(data.headers).forEach(([n, v]) => {
- request.setRequestHeader(n, v)
- })
- request.send(isGet ? void 0 : typeof data.body === 'string' ? data.body : JSON.stringify(data.body))
- saveCache({ method, url, data: dataCode })
- error_tip.innerText = ''
- }, e => {
- error_tip.innerText = String(e)
- })
- })
- function tryTo(fn, errorCallback) {
- return function (...args) {
- try {
- fn.apply(this, args)
- } catch (e) {
- console.error(e)
- errorCallback?.(e)
- }
- }
- }
- function serializeQueryParam(param, prefix = '?') {
- if (!param) return ''
- if (typeof param === 'string') return prefix + param
- const str = Object.entries(param).map(([k, v]) => k + '=' + encodeURIComponent(String(v))).join('&')
- if (str) return prefix + str
- return str
- }
- function saveCache(obj) {
- localStorage.setItem(namespace, JSON.stringify(obj))
- }
- function getCache() {
- const str = localStorage.getItem(namespace)
- try {
- if (str) return JSON.parse(str)
- } catch (e) {
- console.error(e)
- }
- }
- })()