Tampermonkey脚本触发405错误问题排查与优化请求
解决Firefox Portal页面自动确认的405错误(无setTimeout方案)
问题根源
你遇到的405错误大概率是setTimeout的时间设置不合理导致的:按钮虽然在DOM中已存在,但页面底层的表单提交逻辑(比如请求方法、参数初始化)还未完成,过早点击会触发不符合服务器要求的请求,返回405 Method Not Allowed。
替代方案:用DOM监听/精准轮询确保按钮可交互
以下两种方案都能避免setTimeout的不确定性,确保只有当按钮真正可点击时才触发操作:
方案1:MutationObserver监听DOM变化(推荐)
通过监听页面DOM的变化,精准捕捉确认按钮的出现及可交互状态:
// ==UserScript== // @name Auto Confirm Firefox Portal // @namespace http://tampermonkey.net/ // @version 0.1 // @description Auto click confirm button on detectportal.firefox.com without setTimeout // @author You // @match https://detectportal.firefox.com/* // @grant none // ==/UserScript== (function() { 'use strict'; // 替换为页面中确认按钮的实际选择器(查看页面源码获取,比如id/class或文本) const confirmBtnSelector = 'button:contains("确认")'; const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.addedNodes.length) { const confirmBtn = document.querySelector(confirmBtnSelector); // 检查按钮存在且未被禁用 if (confirmBtn && !confirmBtn.disabled) { // 模拟真实鼠标点击(比直接调用click()更接近手动操作) confirmBtn.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })); observer.disconnect(); // 完成后停止监听 break; } } } }); // 监听body下所有DOM变化,包括子节点和按钮禁用状态 observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['disabled'] }); // 初始检查:防止脚本运行时页面已加载完成 const initialBtn = document.querySelector(confirmBtnSelector); if (initialBtn && !initialBtn.disabled) { initialBtn.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })); observer.disconnect(); } })();
方案2:requestAnimationFrame精准轮询
利用浏览器渲染周期进行轮询,比setTimeout更高效且时机更准确:
// ==UserScript== // @name Auto Confirm Firefox Portal // @namespace http://tampermonkey.net/ // @version 0.1 // @description Auto click confirm button on detectportal.firefox.com without setTimeout // @author You // @match https://detectportal.firefox.com/* // @grant none // ==/UserScript== (function() { 'use strict'; const confirmBtnSelector = 'button:contains("确认")'; function checkAndClick() { const confirmBtn = document.querySelector(confirmBtnSelector); if (confirmBtn && !confirmBtn.disabled) { confirmBtn.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })); return; } // 未找到则继续下一轮渲染周期检查 requestAnimationFrame(checkAndClick); } // 页面加载完成后启动检查 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', checkAndClick); } else { checkAndClick(); } })();
关键注意事项
- 选择器准确性:一定要替换
confirmBtnSelector为页面中确认按钮的实际选择器。比如如果按钮文本是英文的“Continue”,就改成button:contains("Continue");如果按钮有id#confirm-btn,直接用该id选择器更可靠。 - 模拟真实点击:使用
dispatchEvent触发鼠标点击事件,而非直接调用confirmBtn.click(),可以避免部分页面的防自动点击逻辑,同时确保触发完整的提交流程。
内容的提问来源于stack exchange,提问作者Bill Joe
相关产品推荐
相关产品推荐

