本地UserScript通过AdGuard注入失败及多网站适配问题求助
问题解答
1. AdGuard无法注入本地脚本的原因及解决
- 核心原因:你的脚本设置了
@run-at document-start,此时document.body尚未创建,执行document.body.appendChild(button)会直接报错,导致脚本终止。本地加载/AdGuard注入时,浏览器严格遵循document-start的执行时机,而远程URL加载可能因缓存或扩展机制差异,实际执行时机延后,因此能正常运行。 - 解决步骤:
- 调整
@run-at为document-body或document-end,确保DOM已初始化; - 检查AdGuard的「用户脚本」设置,确认已开启「允许访问本地文件」权限;
- 本地脚本路径需使用绝对路径(如
file:///C:/Users/xxx/title.user.js),避免相对路径导致AdGuard无法识别。
- 调整
2. 绕过网站JavaScript注入拦截
部分网站(如Stack Overflow)通过内容安全策略(CSP)或DOM防护机制拦截自定义脚本注入,可通过以下方式绕过:
- 使用专属API创建元素:添加
@grant GM_addElement权限,用官方API创建元素,避免直接操作DOM被拦截:// ==UserScript== // @name Button // @run-at document-body // @include * // @grant GM_addElement // @noframes // @version 0.0.2 // ==/UserScript== (function () { const button = GM_addElement('button', { innerHTML: 'Title', style: 'top:0;right:0;position:absolute;background:#4CAF50;z-index:99999' }); button.onclick = () => alert('Hey'); })() - 延迟执行+DOM监听:确保脚本在页面完全渲染后执行:
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } function init() { // 按钮创建逻辑 } - AdGuard自定义CSP规则:在AdGuard「自定义规则」中添加目标网站的放行规则,例如:
stackoverflow.com#$scriptinject('unsafe-inline')
3. 让脚本适配各类网站正常显示
针对RTL网站、不同样式的网站,需优化按钮的样式和定位逻辑:
- 适配RTL布局:动态检测页面布局方向,调整按钮定位:
const isRTL = document.documentElement.dir === 'rtl' || getComputedStyle(document.documentElement).direction === 'rtl'; button.style[isRTL ? 'left' : 'right'] = '0px'; - 提升按钮层级:设置足够高的
z-index避免被遮挡:button.style.zIndex = '99999'; - 重置默认样式:清除按钮默认样式,避免被网站CSS覆盖:
button.style.border = 'none'; button.style.padding = '8px 16px'; button.style.color = 'white'; button.style.cursor = 'pointer'; button.style.fontSize = '14px'; - 容错处理:确保
document.body存在再执行添加逻辑:function init() { if (!document.body) return setTimeout(init, 100); // 创建按钮并添加到body }
优化后的完整脚本
// ==UserScript== // @name Button // @run-at document-body // @include * // @grant none // @noframes // @version 0.0.2 // ==/UserScript== (function () { function init() { if (!document.body) return setTimeout(init, 100); const button = document.createElement("Button"); button.innerHTML = "Title"; // 基础样式 const baseStyle = ` top: 0; position: absolute; background: #4CAF50; z-index: 99999; border: none; padding: 8px 16px; color: white; cursor: pointer; font-size: 14px; `; button.style.cssText = baseStyle; // 适配RTL布局 const isRTL = document.documentElement.dir === 'rtl' || getComputedStyle(document.documentElement).direction === 'rtl'; button.style[isRTL ? 'left' : 'right'] = '0px'; document.body.appendChild(button); button.onclick = function() { alert('Hey'); }; } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })()
内容的提问来源于stack exchange,提问作者Tathastu Pandya
相关产品推荐
相关产品推荐

