您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
[Captured Unique AJAX Paths] 记录页面所有的 Ajax 请求,并支持复制全部,自动过滤重复
// ==UserScript== // @name [Captured Unique AJAX Paths] 记录页面所有的 Ajax 请求 // @namespace http://tampermonkey.net/ // @version 1.12 // @description [Captured Unique AJAX Paths] 记录页面所有的 Ajax 请求,并支持复制全部,自动过滤重复 // @match *://*/* // @grant none // @author Enda // @license MIT // ==/UserScript== (function() { 'use strict'; const paths = new Set(); let isVisible = false; // 用于跟踪浮窗的显示状态 // 创建一个浮动窗口,显示并复制接口路径 const displayBox = document.createElement('div'); displayBox.style.position = 'fixed'; displayBox.style.bottom = '10px'; displayBox.style.right = '10px'; displayBox.style.width = '800px'; // 可以适当缩小宽度 displayBox.style.maxHeight = '800px'; // 设置最大高度 displayBox.style.overflowY = 'auto'; // 启用垂直滚动条 displayBox.style.backgroundColor = '#fff'; displayBox.style.border = '1px solid #ccc'; displayBox.style.padding = '10px'; displayBox.style.fontSize = '13px'; // 增大整体字体 displayBox.style.lineHeight = '2.0'; // 增加行高 displayBox.style.zIndex = '10000'; displayBox.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)'; displayBox.style.display = 'none'; // 默认显示 displayBox.innerHTML = ` <strong>Captured Unique AJAX Paths</strong><br> <button id="copyPaths" style="margin: 5px 0; padding: 5px; cursor: pointer;">Copy All</button> <button id="clearPaths" style="margin: 5px 0; padding: 5px; cursor: pointer;">Clear All</button> <div id="pathList"></div>`; document.body.appendChild(displayBox); const pathList = document.getElementById('pathList'); const copyButton = document.getElementById('copyPaths'); const clearButton = document.getElementById('clearPaths'); copyButton.onclick = () => { const allPaths = Array.from(paths).join('\n'); navigator.clipboard.writeText(allPaths).then(() => { }); }; clearButton.onclick = () => { paths.clear(); // 清空存储的路径 pathList.innerHTML = ''; // 清空显示的路径 }; // 添加隐藏按钮 const toggleButton = document.createElement('button'); toggleButton.textContent = '⚙️'; // 使用小图标作为按钮 toggleButton.style.position = 'fixed'; toggleButton.style.bottom = '10px'; toggleButton.style.right = '10px'; toggleButton.style.fontSize = '20px'; toggleButton.style.zIndex = '10001'; // 确保在浮动窗口之上 toggleButton.style.backgroundColor = 'transparent'; toggleButton.style.border = 'none'; toggleButton.style.cursor = 'pointer'; document.body.appendChild(toggleButton); // 切换浮动窗口的显示和隐藏 toggleButton.onclick = () => { isVisible = !isVisible; // 切换状态 displayBox.style.display = isVisible ? 'block' : 'none'; }; // Function to process and store unique path with parameters without domain function capturePath(url) { try { const urlObj = new URL(url, location.origin); let pathWithParams = urlObj.pathname; if (urlObj.pathname == '/index.php'){ const urlParams = new URLSearchParams(urlObj.search); const [app, mod, act] = [urlParams.get('app'), urlParams.get('mod'), urlParams.get('act')]; // 只有当 app, mod, act 都存在时,才构建新的路径 if (app && mod && act) { pathWithParams = `/${app}/${mod}/${act}`; } } if (!paths.has(pathWithParams)) { paths.add(pathWithParams); const pathItem = document.createElement('div'); pathItem.textContent = pathWithParams; pathItem.style.fontSize = '13px'; // 增大单行字体 pathItem.style.lineHeight = '2.0'; // 增加单行行高 pathList.appendChild(pathItem); } } catch (error) { console.error('Error processing URL:', url); } } // Intercept XMLHttpRequest requests const originalOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url, async, user, password) { this._url = url; return originalOpen.apply(this, arguments); }; const originalSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(body) { this.addEventListener('load', () => capturePath(this._url)); return originalSend.apply(this, arguments); }; // Intercept fetch requests const originalFetch = window.fetch; window.fetch = async function(input, init) { const url = input instanceof Request ? input.url : input; const response = await originalFetch(input, init); capturePath(url); return response; }; })();