Greasy Fork

Greasy Fork is available in English.

ad 反广告检测bypass

提高稳定性与性能,增加自定义排除功能,确保不会干扰扫码验证等功能,优化错误处理和性能

当前为 2025-02-27 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name            ad 反广告检测bypass 
// @version         1.1.0
// @description     提高稳定性与性能,增加自定义排除功能,确保不会干扰扫码验证等功能,优化错误处理和性能
// @match           *://*/*
// @run-at          document-start
// @grant           none
// @license         MIT
// @namespace       http://greasyfork.icu/users/1440075
// ==/UserScript==

(function() {
    'use strict';
    try {
        // 备份原始的 getComputedStyle 函数
        const originalGetComputedStyle = window.getComputedStyle;

        // 用于缓存检测过的元素状态,避免重复检测
        const elementCache = new WeakMap();

        // 用户自定义排除关键词
        const userExcludedKeywords = [
            'qr', 'verify', 'captcha', 'validate', 'recaptcha', 'g-recaptcha',
            'security', 'auth', '扫码', '验证', '验证码', 'popup', 'modal', 'overlay'
        ];

        // 排除广告相关的常见 HTML 标签
        const adElementTags = ['IMG', 'IFRAME', 'SCRIPT', 'DIV', 'SPAN', 'BANNER'];

        // 优化错误处理和日志输出
        function logError(message, data = {}) {
            console.error(message, data);
        }

        // 重写 getComputedStyle,支持第二个参数 pseudoElement
        Object.defineProperty(window, "getComputedStyle", {
            get() {
                return function(element, pseudoElement) {
                    try {
                        // 如果请求的是伪元素,则直接返回原始结果
                        if (pseudoElement) {
                            return originalGetComputedStyle(element, pseudoElement);
                        }

                        // 检查缓存,减少重复检查
                        if (elementCache.has(element)) {
                            return elementCache.get(element);
                        }

                        // 获取原始样式对象
                        const style = originalGetComputedStyle(element, pseudoElement);

                        // 排除验证相关元素
                        if (element && typeof element.getAttribute === 'function') {
                            const idStr = element.id ? element.id.toLowerCase() : "";
                            const classStr = (typeof element.className === 'string' ? element.className.toLowerCase() : "");
                            if (userExcludedKeywords.some(kw => idStr.includes(kw) || classStr.includes(kw))) {
                                elementCache.set(element, style);
                                return style;
                            }
                        }

                        // 排除广告元素(通过标签类型)
                        if (adElementTags.includes(element.tagName)) {
                            const isAd = (
                                element.src && (element.src.includes('ad') || element.src.includes('banner') || element.src.includes('ads')) ||
                                element.id && element.id.includes('ad') ||
                                element.className && element.className.includes('ad') ||
                                element.style && element.style.display === 'none'
                            );
                            if (isAd && style.display === "none") {
                                const proxyStyle = new Proxy(style, {
                                    get(target, prop, receiver) {
                                        if (prop === "display") {
                                            return "block";
                                        }
                                        return Reflect.get(target, prop, receiver);
                                    }
                                });
                                elementCache.set(element, proxyStyle);
                                return proxyStyle;
                            }
                        }

                        // 默认返回原始样式对象
                        elementCache.set(element, style);
                        return style;
                    } catch (e) {
                        logError("getComputedStyle 重写异常:", e);
                        return originalGetComputedStyle(element, pseudoElement);
                    }
                };
            },
            configurable: true,
            enumerable: true
        });
    } catch (e) {
        console.error("全局脚本异常:", e);
    }
})();