Greasy Fork

Greasy Fork is available in English.

网站数据清除工具 Website Data Cleaner

油猴菜单触发,一键清除当前网站的localStorage、sessionStorage、Cookie、IndexedDB、Web SQL数据

当前为 2025-11-20 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         网站数据清除工具 Website Data Cleaner
// @namespace    http://tampermonkey.net/
// @version      1.1.0
// @description  油猴菜单触发,一键清除当前网站的localStorage、sessionStorage、Cookie、IndexedDB、Web SQL数据
// @author       ChiamZhang
// @match        *://*/*
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_openInTab
// @run-at       document-end
// @license MIT表
// ==/UserScript==

(function() {
    'use strict';

    // ================= 全局变量 =================
    const menuId = []; // 存储菜单ID,用于后续注销
    // 菜单配置(参考用户提供的格式)
    const menuAll = [
        ['menu_clearAll', '清除当前网站所有数据', '清除所有数据', false], // [ID, 菜单名称, 描述, 状态]
        ['menu_clearBasic', '仅清除 localStorage + SessionStorage', '基础存储清除', false],
        ['menu_clearCookie', '仅清除当前网站Cookie', 'Cookie清除', false],
        ['menu_clearDB', '仅清除 IndexedDB + Web SQL', '数据库清除', false]
    ];

    // ================= 核心清除函数 =================
    /**
     * 清除localStorage
     */
    function clearLocalStorage() {
        try {
            localStorage.clear();
            console.log('[数据清除] localStorage 清除成功');
            return true;
        } catch (e) {
            console.error('[数据清除] localStorage 清除失败:', e);
            return false;
        }
    }

    /**
     * 清除sessionStorage
     */
    function clearSessionStorage() {
        try {
            sessionStorage.clear();
            console.log('[数据清除] sessionStorage 清除成功');
            return true;
        } catch (e) {
            console.error('[数据清除] sessionStorage 清除失败:', e);
            return false;
        }
    }

    /**
     * 清除当前网站的Cookie
     */
    function clearCookies() {
        try {
            const cookies = document.cookie.split(';');
            const domain = window.location.hostname;

            // 兼容不同子域名和路径的Cookie清除
            cookies.forEach(cookie => {
                const eqPos = cookie.indexOf('=');
                const name = eqPos > -1 ? cookie.substr(0, eqPos).trim() : cookie.trim();

                // 多场景清除确保生效
                document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${domain}; SameSite=None; Secure`;
                document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${domain}; SameSite=None; Secure`;
                document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=None; Secure`;
                document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/${domain}; SameSite=None; Secure`;
            });

            console.log('[数据清除] Cookie 清除成功(共', cookies.length, '个)');
            return true;
        } catch (e) {
            console.error('[数据清除] Cookie 清除失败:', e);
            return false;
        }
    }

    /**
     * 清除IndexedDB
     */
    async function clearIndexedDB() {
        try {
            if (!window.indexedDB) return true;

            const databases = await indexedDB.databases();
            if (databases.length === 0) return true;

            for (const db of databases) {
                await new Promise((resolve) => {
                    const request = indexedDB.deleteDatabase(db.name);
                    request.onsuccess = () => resolve(true);
                    request.onerror = (err) => {
                        console.warn(`[数据清除] IndexedDB ${db.name} 清除失败:`, err);
                        resolve(false);
                    };
                    request.onblocked = () => {
                        console.warn(`[数据清除] IndexedDB ${db.name} 被占用(可能有其他标签页打开)`);
                        resolve(false);
                    };
                });
            }

            console.log('[数据清除] IndexedDB 清除完成(共', databases.length, '个数据库)');
            return true;
        } catch (e) {
            console.error('[数据清除] IndexedDB 清除异常:', e);
            return false;
        }
    }

    /**
     * 清除Web SQL
     */
    function clearWebSQL() {
        try {
            if (!window.openDatabase) return true;

            // 遍历常见的Web SQL数据库名称模式
            const dbNamePatterns = ['web sql', 'site_', 'app_', 'local_', 'data_', 'db_'];
            let clearedCount = 0;

            dbNamePatterns.forEach(pattern => {
                try {
                    // 尝试打开并删除匹配的数据库
                    const db = openDatabase(
                        `temp_${pattern}`,
                        '1.0',
                        'Temporary database for deletion',
                        1024 * 1024
                    );
                    db.transaction(tx => {
                        tx.executeSql('DROP TABLE IF EXISTS main');
                        clearedCount++;
                    });
                } catch (e) {}
            });

            console.log('[数据清除] Web SQL 清除完成(处理', clearedCount, '个匹配模式)');
            return true;
        } catch (e) {
            console.error('[数据清除] Web SQL 清除异常:', e);
            return true; // Web SQL兼容性较差,失败不影响整体流程
        }
    }

    // ================= 功能入口函数 =================
    /**
     * 显示操作结果通知
     * @param {string} message 通知内容
     * @param {boolean} success 是否成功
     */
    function showResult(message, success = true) {
        // 优先使用浏览器通知API
        if (Notification.permission === 'granted') {
            new Notification('网站数据清除工具', { body: message });
        } else if (Notification.permission !== 'denied') {
            Notification.requestPermission().then(perm => {
                if (perm === 'granted') {
                    new Notification('网站数据清除工具', { body: message });
                }
            });
        }

        // 控制台打印详细信息
        console.log(`[数据清除${success ? '成功' : '失败'}]`, message);

        // 页面顶部临时提示(避免完全无反馈)
        const toast = document.createElement('div');
        toast.style.cssText = `
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            padding: 12px 24px;
            border-radius: 4px;
            background: ${success ? '#4CAF50' : '#f44336'};
            color: white;
            font-size: 14px;
            z-index: 999999;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            opacity: 0;
            transition: opacity 0.3s ease;
        `;
        toast.textContent = message;
        document.body.appendChild(toast);

        setTimeout(() => toast.style.opacity = '1', 10);
        setTimeout(() => {
            toast.style.opacity = '0';
            setTimeout(() => document.body.removeChild(toast), 300);
        }, 3000);
    }

    /**
     * 清除所有数据(完整模式)
     */
    async function clearAllData() {
        if (!confirm('⚠️ 确认清除当前网站所有数据?\n包含:localStorage、SessionStorage、Cookie、IndexedDB、Web SQL\n清除后不可恢复,登录状态会失效!')) {
            return;
        }

        try {
            const results = [
                clearLocalStorage(),
                clearSessionStorage(),
                clearCookies(),
                await clearIndexedDB(),
                clearWebSQL()
            ];

            const hasFailure = results.some(res => !res);
            if (hasFailure) {
                showResult('部分数据清除成功,部分数据可能未清除(详见控制台)', false);
            } else {
                showResult('✅ 当前网站所有数据清除成功!');
                // 可选:清除后刷新页面(取消注释启用)
                // if (confirm('是否刷新页面使清除生效?')) location.reload();
            }
        } catch (e) {
            showResult('❌ 数据清除过程中发生错误', false);
            console.error('[数据清除] 全局异常:', e);
        }
    }

    /**
     * 仅清除基础存储(localStorage + SessionStorage)
     */
    function clearBasicData() {
        if (!confirm('确认清除当前网站的localStorage和SessionStorage?\n这会清除网站保存的本地设置和临时数据!')) {
            return;
        }

        const res1 = clearLocalStorage();
        const res2 = clearSessionStorage();

        if (res1 && res2) {
            showResult('✅ 基础存储数据清除成功!');
        } else {
            showResult('❌ 基础存储数据清除失败', false);
        }
    }

    /**
     * 仅清除Cookie
     */
    function clearOnlyCookie() {
        if (!confirm('确认清除当前网站的所有Cookie?\n这会导致登录状态失效,需要重新登录!')) {
            return;
        }

        const res = clearCookies();
        if (res) {
            showResult('✅ Cookie清除成功!');
        } else {
            showResult('❌ Cookie清除失败', false);
        }
    }

    /**
     * 仅清除数据库(IndexedDB + Web SQL)
     */
    async function clearOnlyDB() {
        if (!confirm('确认清除当前网站的IndexedDB和Web SQL数据库?\n这会清除网站保存的离线数据和缓存内容!')) {
            return;
        }

        const res1 = await clearIndexedDB();
        const res2 = clearWebSQL();

        if (res1 && res2) {
            showResult('✅ 数据库数据清除成功!');
        } else {
            showResult('部分数据库可能未清除(可能被占用)', false);
        }
    }

    // ================= 菜单注册函数 =================
    /**
     * 注册油猴菜单(参考用户提供的代码风格)
     */
    function registerMenuCommand() {
        // 先注销已存在的菜单,避免重复
        if (menuId.length > 0) {
            menuId.forEach(id => {
                try { GM_unregisterMenuCommand(id); } catch (e) {}
            });
            menuId.length = 0; // 清空数组
        }

        // 循环注册菜单
        for (let i = 0; i < menuAll.length; i++) {
            const [menuKey, menuName, menuDesc, menuState] = menuAll[i];

            // 从存储中读取菜单状态(如果有)
            menuAll[i][3] = GM_getValue(menuKey, menuState);

            // 根据菜单ID绑定对应的功能
            switch (menuKey) {
                case 'menu_clearAll':
                    menuId[i] = GM_registerMenuCommand(`🗑️ ${menuName}`, clearAllData);
                    break;
                case 'menu_clearBasic':
                    menuId[i] = GM_registerMenuCommand(`📦 ${menuName}`, clearBasicData);
                    break;
                case 'menu_clearCookie':
                    menuId[i] = GM_registerMenuCommand(`🍪 ${menuName}`, clearOnlyCookie);
                    break;
                case 'menu_clearDB':
                    menuId[i] = GM_registerMenuCommand(`🗄️ ${menuName}`, clearOnlyDB);
                    break;
                case 'menu_feedback':
                    menuId[i] = GM_registerMenuCommand(`💬 ${menuName}`, openFeedback);
                    break;
                default:
                    // 通用菜单模板(如果需要开关状态)
                    menuId[i] = GM_registerMenuCommand(
                        `${menuAll[i][3] ? '✅' : '❌'} ${menuName}`,
                        () => menuSwitch(menuAll[i][3], menuKey, menuDesc)
                    );
            }
        }
    }

    /**
     * 菜单开关状态切换(预留功能,当前版本未使用)
     * @param {boolean} currentState 当前状态
     * @param {string} menuKey 菜单ID
     * @param {string} menuDesc 菜单描述
     */
    function menuSwitch(currentState, menuKey, menuDesc) {
        const newState = !currentState;
        GM_setValue(menuKey, newState);
        showResult(`${menuDesc}已${newState ? '启用' : '禁用'}`);
        // 重新注册菜单更新状态显示
        registerMenuCommand();
    }

    // ================= 初始化 =================
    // 检查通知权限(可选,提升用户体验)
    if (Notification.permission !== 'granted' && Notification.permission !== 'denied') {
        // 不主动请求,避免打扰用户,仅在首次使用时提示
        console.log('[数据清除工具] 可在浏览器设置中开启通知权限,获取清除结果提醒');
    }

    // 注册菜单(确保菜单ID长度正常)
    if (menuId.length < 4) {
        registerMenuCommand();
    }

    console.log('[数据清除工具] 菜单已加载完成,可在油猴菜单中操作');
})();