Bilibili Cookie Getter

获取哔哩哔哩网站的cookie

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Bilibili Cookie Getter
// @namespace    http://tampermonkey.net/
// @version      1.6
// @description  获取哔哩哔哩网站的cookie
// @author       Your name
// @match        *://*.bilibili.com/*
// @grant        GM_setClipboard
// @grant        GM_notification
// @grant        GM_cookie
// @grant        GM.cookie
// @grant        GM_xmlhttpRequest
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        unsafeWindow
// @connect      *
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // 重要cookie列表
    const IMPORTANT_COOKIES = [
        'DedeUserID',
        'bili_jct',
        'SESSDATA',
        'bili_ticket',
        'sid'
    ];

    // 新增:指定的cookie
    const SPECIFIED_COOKIE = 'single_unread';

    // 格式化cookie字符串
    function formatCookies(cookieStr) {
        const cookieMap = new Map();
        cookieStr.split(';').forEach(cookie => {
            const [key, value] = cookie.trim().split('=');
            cookieMap.set(key, value);
        });

        // 首先添加��cookie
        let result = '// 重要Cookie:\n';
        IMPORTANT_COOKIES.forEach(key => {
            if (cookieMap.has(key)) {
                result += `${key}=${cookieMap.get(key)};\n`;
                cookieMap.delete(key);
            }
        });

        // 添加其他cookie
        result += '\n// 其他Cookie:\n';
        cookieMap.forEach((value, key) => {
            result += `${key}=${value};\n`;
        });

        return result;
    }

    // 只获取重要cookie
    function getImportantCookies(cookieStr) {
        const cookieMap = new Map();
        cookieStr.split(';').forEach(cookie => {
            const [key, value] = cookie.trim().split('=');
            if (IMPORTANT_COOKIES.includes(key)) {
                cookieMap.set(key, value);
            }
        });

        return Array.from(cookieMap)
            .map(([key, value]) => `${key}=${value}`)
            .join(';\n');
    }

    // 添加常量定义
    const MAX_RETRIES = 3;
    const MAX_CONCURRENT = 5;
    const COOKIE_DOMAINS = [
        'bilibili.com',
        '.bilibili.com',
        'www.bilibili.com',
        'api.bilibili.com',
        'passport.bilibili.com'
    ];

    // 修改 fetchWithRetry 函数
    async function fetchWithRetry(endpoint, retryCount = 0) {
        try {
            const response = await new Promise((resolve, reject) => {
                const requestOptions = {
                    method: endpoint.method,
                    url: endpoint.url,
                    headers: {
                        'User-Agent': navigator.userAgent,
                        'Cookie': document.cookie,
                        'Referer': 'https://www.bilibili.com',
                        'Origin': 'https://www.bilibili.com',
                        'Accept': 'application/json, text/plain, */*',
                        'Connection': 'keep-alive',
                        'Sec-Fetch-Site': 'same-site',
                        'Sec-Fetch-Mode': 'cors',
                        'Sec-Fetch-Dest': 'empty',
                        'X-Requested-With': 'XMLHttpRequest',
                        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
                        'Accept-Encoding': 'gzip, deflate, br',
                        // 添加更多请求头
                        'Cache-Control': 'no-cache',
                        'Pragma': 'no-cache',
                        'X-CSRF-TOKEN': document.cookie.match(/bili_jct=([^;]+)/)?.[1] || '',
                        'X-Requested-With': 'XMLHttpRequest'
                    },
                    withCredentials: true,
                    timeout: 5000,
                    anonymous: false,
                    onload: resolve,
                    onerror: reject,
                    // 添加更多选项
                    nocache: true,
                    revalidate: true
                };

                // 添加特定的请求头
                if (endpoint.headers) {
                    Object.assign(requestOptions.headers, endpoint.headers);
                }

                GM_xmlhttpRequest(requestOptions);
            });

            return response;
        } catch (error) {
            if (retryCount < MAX_RETRIES) {
                console.log(`重试请求 ${endpoint.url} (${retryCount + 1}/${MAX_RETRIES})`);
                await new Promise(resolve => setTimeout(resolve, 1000 * (retryCount + 1)));
                return fetchWithRetry(endpoint, retryCount + 1);
            }
            throw error;
        }
    }

    // 添加新的cookie获取函数
    async function getAllDomainCookies() {
        let allCookies = '';

        // 尝试从所有域名获取cookie
        for (const domain of COOKIE_DOMAINS) {
            try {
                if (typeof GM_cookie !== 'undefined') {
                    const cookies = await new Promise((resolve) => {
                        GM_cookie.list({ domain }, (cookies) => resolve(cookies));
                    });

                    if (cookies && cookies.length > 0) {
                        const domainCookies = cookies
                            .map(cookie => `${cookie.name}=${cookie.value}`)
                            .join('; ');
                        allCookies = allCookies ? `${allCookies}; ${domainCookies}` : domainCookies;
                        console.log(`从域名 ${domain} 获取到 ${cookies.length} 个cookie`);
                    }
                }
            } catch (error) {
                console.log(`获取 ${domain} 的cookie失败:`, error);
            }
        }

        return allCookies;
    }

    // 添加新的函数来处理响应
    function processResponse(response) {
        if (!response || !response.responseHeaders) return '';

        let newCookies = '';

        try {
            // 1. 从响应头获取cookie
            const headers = response.responseHeaders.toLowerCase();
            const allHeaders = headers.split('\n');

            // 处理所有可能的cookie头
            const cookieHeaders = allHeaders.filter(h =>
                h.includes('cookie') ||
                h.includes('set-cookie') ||
                h.includes('x-set-cookie')
            );

            if (cookieHeaders.length > 0) {
                newCookies = cookieHeaders
                    .map(header => {
                        const [_, value] = header.split(':', 2);
                        return value ? value.trim() : '';
                    })
                    .filter(Boolean)
                    .join('; ');
            }

            // 2. 从响应体获取cookie
            try {
                const data = JSON.parse(response.responseText);
                if (data && typeof data === 'object') {
                    const extractCookies = (obj, path = '') => {
                        let extracted = '';
                        for (const [key, value] of Object.entries(obj)) {
                            if (typeof value === 'object' && value !== null) {
                                extracted += extractCookies(value, `${path}${key}.`);
                            } else if (
                                (key.toLowerCase().includes('cookie') ||
                                key.toLowerCase().includes('token')) &&
                                typeof value === 'string'
                            ) {
                                console.log(`在路径 ${path}${key} 找到可能的cookie值`);
                                extracted += value + '; ';
                            }
                        }
                        return extracted;
                    };

                    const bodyCookies = extractCookies(data);
                    if (bodyCookies) {
                        newCookies = newCookies ? `${newCookies}; ${bodyCookies}` : bodyCookies;
                    }
                }
            } catch (e) {
                // 忽略JSON解析错误
            }

            return newCookies;
        } catch (error) {
            console.error('处理响应失败:', error);
            return '';
        }
    }

    // 修改 getExtendedCookies 函数
    async function getExtendedCookies() {
        let allCookies = new Set();

        // 1. 获取当前域名的所有cookie
        document.cookie.split(';').forEach(cookie =>
            allCookies.add(cookie.trim())
        );

        // 2. 尝试从所有域名获取cookie
        const domainCookies = await getAllDomainCookies();
        if (domainCookies) {
            domainCookies.split(';').forEach(cookie =>
                allCookies.add(cookie.trim())
            );
        }

        // 3. 尝试从localStorage获取相关信息
        try {
            for (let i = 0; i < localStorage.length; i++) {
                const key = localStorage.key(i);
                if (key.toLowerCase().includes('cookie') ||
                    key.toLowerCase().includes('token') ||
                    key.toLowerCase().includes('auth')) {
                    const value = localStorage.getItem(key);
                    if (value && value.includes('=')) {
                        allCookies.add(value.trim());
                    }
                }
            }
        } catch (e) {
            console.log('localStorage访问失败:', e);
        }

        // 4. 处理所有请求
        const allEndpoints = [
            // 基础API
            { url: 'https://api.bilibili.com/x/web-interface/nav', method: 'GET' },
            { url: 'https://api.bilibili.com/x/web-interface/nav/stat', method: 'GET' },
            // 用户相关
            { url: 'https://api.bilibili.com/x/space/myinfo', method: 'GET' },
            { url: 'https://api.bilibili.com/x/space/acc/info', method: 'GET' },
            // 视频相关
            { url: 'https://api.bilibili.com/x/player/v2', method: 'GET' },
            { url: 'https://api.bilibili.com/x/player/wbi/playurl', method: 'GET' },
            // 直播相关
            { url: 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser', method: 'GET' },
            { url: 'https://live.bilibili.com/p/html/live-web-mng/index', method: 'GET' },
            // 消息相关
            { url: 'https://message.bilibili.com/api/notify/query.notify.count.do', method: 'GET' },
            // 动态相关
            { url: 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new', method: 'GET' },
            // 特殊请求
            {
                url: 'https://www.bilibili.com/correspond/1',
                method: 'GET',
                headers: { 'X-From-Bili': 'main' }
            },
            {
                url: 'https://api.bilibili.com/x/web-show/res/locs',
                method: 'GET',
                headers: { 'X-From-Bili': 'main' }
            },
            // POST请求
            {
                url: 'https://api.bilibili.com/x/web-interface/nav',
                method: 'POST',
                data: {
                    build: 0,
                    mobi_app: 'web',
                    csrf: document.cookie.match(/bili_jct=([^;]+)/)?.[1] || ''
                }
            },
            {
                url: 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser',
                method: 'POST',
                data: {
                    room_id: 0,
                    platform: 'web'
                }
            },
            // 动态资源
            {
                url: 'https://www.bilibili.com/favicon.ico',
                method: 'GET',
                headers: { 'Accept': 'image/webp,*/*' }
            },
            {
                url: 'https://static.hdslb.com/images/favicon.ico',
                method: 'GET',
                headers: { 'Accept': 'image/webp,*/*' }
            }
        ];

        // 添加动态端点
        try {
            const uid = document.cookie.match(/DedeUserID=(\d+)/)?.[1];
            if (uid) {
                allEndpoints.push(
                    { url: `https://api.bilibili.com/x/space/upstat?mid=${uid}`, method: 'GET' },
                    { url: `https://api.bilibili.com/x/relation/stat?vmid=${uid}`, method: 'GET' }
                );
            }
        } catch (error) {
            console.log('获取UID失败:', error);
        }

        // 5. 并发处理请求
        const results = await Promise.allSettled(
            allEndpoints.map(endpoint =>
                endpoint.method !== 'WS' ?
                    fetchWithRetry(endpoint) :
                    Promise.resolve(null)
            )
        );

        // 6. 处理响应
        results.forEach(result => {
            if (result.status === 'fulfilled' && result.value) {
                const cookies = processResponse(result.value);
                if (cookies) {
                    cookies.split(';').forEach(cookie =>
                        allCookies.add(cookie.trim())
                    );
                }
            }
        });

        // 7. 返回去重后的有效cookie
        return Array.from(allCookies)
            .filter(cookie => {
                const [key, value] = cookie.split('=');
                return key && value && !key.includes(' ');
            })
            .join('; ');
    }

    // 修改cookie证和清理函数
    function validateAndCleanCookies(cookies) {
        // 已知的有效cookie名称列表
        const knownCookies = new Set([
            // 用户认证相关
            'DedeUserID', 'DedeUserID__ckMd5', 'bili_jct', 'SESSDATA',
            'bili_ticket', 'bili_ticket_expires', 'sid',
            // 设备和浏览器标识
            'buvid3', 'buvid4', 'buvid_fp', 'buvid_fp_plain',
            '_uuid', 'fingerprint', 'b_lsid', 'b_nut',
            // 功能和设置相关
            'CURRENT_FNVAL', 'CURRENT_QUALITY', 'CURRENT_BLACKGAP',
            'CURRENT_QUALITY_CROSS_PAGE', 'browser_resolution',
            'header_theme_version', 'home_feed_column', 'enable_web_push',
            'go-back-dyn', 'is-2022-channel',
            // 直播相关
            'LIVE_BUVID', 'live_buvid',
            // 播放器相关
            'bp_video_offset', 'bp_t_offset', 'PVID',
            // 其他系统相关
            'rpdid', 'hit-dyn-v2', 'innersign',
            'bmg_af_switch', 'bmg_src_def_domain',
            'dy_spec_agreed', 'b_timer'
        ]);

        // 分割并过滤cookie
        const cookieSet = new Set(
            cookies.split(';')
                .map(cookie => cookie.trim())
                .filter(cookie => {
                    // 基本验证
                    if (!cookie.includes('=')) return false;
                    const [key, value] = cookie.split('=');
                    if (!key || !value) return false;

                    // 清理key和value
                    const cleanKey = key.trim();
                    const cleanValue = value.trim();

                    // 验证规则
                    if (cleanKey.includes(' ') || cleanKey.length > 100) return false;
                    if (cleanValue.length > 1000) return false;
                    if (cleanValue.includes('\n') || cleanValue.includes('\r')) return false;

                    // 保留规则
                    return knownCookies.has(cleanKey) ||
                           /^bp_t_offset_\d+$/.test(cleanKey) ||
                           /^b_(lsid|nut|uid|timer)/.test(cleanKey) ||
                           /^bili_/.test(cleanKey) ||
                           /^SESSDATA$/.test(cleanKey) ||
                           /^_uuid$/.test(cleanKey) ||
                           /^buvid[0-9]?$/.test(cleanKey);
                })
                .map(cookie => {
                    const [key, value] = cookie.split('=');
                    // 允许更多的特殊字符
                    const cleanValue = value.replace(/[^\w\d\-_.%=:]/g, '');
                    return `${key.trim()}=${cleanValue}`;
                })
        );

        // 转换回字符串
        const result = Array.from(cookieSet).join('; ');
        console.log('验证后的cookie数量:', cookieSet.size);
        return result;
    }

    // 修改 forceGetCookies 函数
    async function forceGetCookies() {
        let allCookies = new Set();

        // 等待页面加载完成
        if (document.readyState !== 'complete') {
            await new Promise(resolve => {
                window.addEventListener('load', resolve);
            });
        }

        // 1. 使用多种方法获取原始cookie
        try {
            // 直接获取
            const currentCookie = document.cookie;
            if (currentCookie && typeof currentCookie === 'string') {
                currentCookie.split(';').forEach(cookie =>
                    allCookies.add(cookie.trim())
                );
            }

            // 使用Object.getOwnPropertyDescriptor
            try {
                const cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') ||
                                  Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie');
                if (cookieDesc && cookieDesc.get) {
                    const cookieStr = cookieDesc.get.call(document);
                    if (cookieStr && typeof cookieStr === 'string') {
                        cookieStr.split(';').forEach(cookie =>
                            allCookies.add(cookie.trim())
                        );
                    }
                }
            } catch (e) {
                console.log('获取cookie描述符失败:', e);
            }

            // 尝试使用CookieStore API
            if ('cookieStore' in window) {
                try {
                    const cookies = await cookieStore.getAll();
                    cookies.forEach(cookie =>
                        allCookies.add(`${cookie.name}=${cookie.value}`)
                    );
                } catch (e) {
                    console.log('CookieStore API访问失败:', e);
                }
            }

        } catch (e) {
            console.log('获取原始cookie失败:', e);
        }

        // 2. 注入cookie监听器
        try {
            const originalSetCookie = document.__lookupSetter__('cookie');
            document.__defineSetter__('cookie', function(val) {
                allCookies.add(val.trim());
                return originalSetCookie.call(document, val);
            });
        } catch (e) {
            console.log('注入cookie监听器失败:', e);
        }

        // 3. 强制触发cookie设置
        try {
            // 触发页面重新加载cookie
            const tempIframe = document.createElement('iframe');
            tempIframe.style.display = 'none';
            tempIframe.src = 'https://www.bilibili.com/';
            document.body.appendChild(tempIframe);
            setTimeout(() => tempIframe.remove(), 1000);

            // 触发API请求
            fetch('https://api.bilibili.com/x/web-interface/nav', {
                credentials: 'include',
                mode: 'cors'
            }).catch(() => {});
        } catch (e) {
            console.log('触发cookie设置失败:', e);
        }

        // 4. 使用特殊的请求头强制获取
        const specialHeaders = {
            'X-Override-Cookie': document.cookie,
            'X-Original-Cookie': document.cookie,
            'Cookie-Debug': 'true',
            'X-Cookie-Debug': 'true'
        };

        // 5. 发送特殊请求
        const urls = [
            'https://api.bilibili.com/x/web-interface/nav',
            'https://passport.bilibili.com/x/passport-login/web/cookie/info',
            'https://www.bilibili.com/'
        ];

        for (const url of urls) {
            try {
                const response = await fetch(url, {
                    credentials: 'include',
                    mode: 'cors',
                    headers: specialHeaders
                });
                const cookies = response.headers.get('set-cookie');
                if (cookies) {
                    cookies.split(',').forEach(cookie =>
                        allCookies.add(cookie.split(';')[0].trim())
                    );
                }
            } catch (e) {
                console.log(`请求 ${url} 失败:`, e);
            }
        }

        // 6. 等待一段时间以确保所有cookie都被设置
        await new Promise(resolve => setTimeout(resolve, 1000));

        // 7. 最后一次获取当前cookie
        document.cookie.split(';').forEach(cookie =>
            allCookies.add(cookie.trim())
        );

        // 8. 返回验证后的cookie
        return validateAndCleanCookies(Array.from(allCookies).join('; '));
    }

    // 修改 getSpecifiedCookie 函数
    async function getSpecifiedCookie() {
        try {
            const allCookies = new Set();

            // 1. 劫持原生API
            const originalDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
            const originalGetter = originalDescriptor.get;
            const originalSetter = originalDescriptor.set;

            // 2. 注入cookie监听器
            Object.defineProperty(Document.prototype, 'cookie', {
                get: function() {
                    const value = originalGetter.call(this);
                    if (value) allCookies.add(value);
                    return value;
                },
                set: function(value) {
                    if (value) allCookies.add(value);
                    return originalSetter.call(this, value);
                },
                configurable: true
            });

            // 3. 使用GM_cookie获取所有域名的cookie
            const domains = [
                'bilibili.com',
                '.bilibili.com',
                'www.bilibili.com',
                'api.bilibili.com',
                'passport.bilibili.com',
                'live.bilibili.com',
                't.bilibili.com',
                'space.bilibili.com',
                'message.bilibili.com',
                'api.vc.bilibili.com'
            ];

            for (const domain of domains) {
                try {
                    const cookies = await new Promise((resolve) => {
                        GM_cookie.list({ domain }, (cookies) => resolve(cookies));
                    });

                    if (cookies && cookies.length > 0) {
                        cookies.forEach(cookie =>
                            allCookies.add(`${cookie.name}=${cookie.value}`)
                        );
                    }
                } catch (e) {}
            }

            // 4. 发送特殊请求
            const specialHeaders = {
                'Accept': 'application/json, text/plain, */*',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRF-TOKEN': document.cookie.match(/bili_jct=([^;]+)/)?.[1] || '',
                'Cookie': document.cookie,
                'X-Cookie': document.cookie,
                'X-Original-Cookie': document.cookie,
                'X-Debug-Cookie': document.cookie,
                'X-Cookie-Debug': 'true',
                // 添加更多特殊头
                'X-Cookie-Override': document.cookie,
                'X-Cookie-All': document.cookie,
                'X-Cookie-Raw': document.cookie,
                'X-Cookie-Full': document.cookie
            };

            const urls = [
                'https://api.bilibili.com/x/web-interface/nav',
                'https://passport.bilibili.com/x/passport-login/web/cookie/info',
                'https://api.bilibili.com/x/web-interface/nav/stat',
                'https://api.bilibili.com/x/player/v2',
                'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser',
                // 添加更多端点
                'https://api.bilibili.com/x/web-interface/wbi/index',
                'https://api.bilibili.com/x/space/wbi/acc/info',
                'https://api.bilibili.com/x/web-interface/search/default',
                'https://api.bilibili.com/x/web-interface/zone',
                'https://api.bilibili.com/x/web-show/res/locs'
            ];

            for (const url of urls) {
                try {
                    const response = await fetch(url, {
                        credentials: 'include',
                        headers: specialHeaders
                    });

                    const setCookie = response.headers.get('set-cookie');
                    if (setCookie) {
                        setCookie.split(',').forEach(cookie => {
                            const mainPart = cookie.split(';')[0];
                            if (mainPart) allCookies.add(mainPart.trim());
                        });
                    }
                } catch (e) {}
                await new Promise(resolve => setTimeout(resolve, 100));
            }

            // 5. 恢复原始API
            Object.defineProperty(Document.prototype, 'cookie', originalDescriptor);

            // 6. 返回所有cookie
            return Array.from(allCookies)
                .filter(cookie => {
                    const [key, value] = cookie.split('=');
                    return key && value && !key.includes(' ');
                })
                .join('; ');

        } catch (error) {
            console.error('获取cookie失败:', error);
            return document.cookie;
        }
    }

    // 显示通知
    function showNotification(message) {
        const toast = document.createElement('div');
        toast.style.cssText = `
            position: fixed;
            top: 70px;
            right: 80px;
            background-color: rgba(34, 34, 34, 0.9);
            color: white;
            padding: 10px 20px;
            border-radius: 4px;
            z-index: 999999999;
            font-size: 14px;
            font-family: Arial, sans-serif;
            animation: fadeInOut 4s ease-in-out;
            white-space: pre-line;
        `;

        const style = document.createElement('style');
        style.textContent = `
            @keyframes fadeInOut {
                0% { opacity: 0; transform: translateY(-20px); }
                15% { opacity: 1; transform: translateY(0); }
                85% { opacity: 1; transform: translateY(0); }
                100% { opacity: 0; transform: translateY(-20px); }
            }
        `;
        document.head.appendChild(style);

        toast.textContent = message;
        document.body.appendChild(toast);

        setTimeout(() => {
            toast.remove();
            style.remove();
        }, 5000);
    }

    // 按钮
    function addButtons() {
        const container = document.createElement('div');
        container.style.cssText = `
            position: fixed;
            top: 70px;
            right: 20px;
            display: flex;
            gap: 10px;
            z-index: 999999;
        `;

        // 完整Cookie按钮
        const fullButton = document.createElement('button');
        fullButton.textContent = '获取Cookie';
        fullButton.style.cssText = `
            padding: 8px 16px;
            background: #fb7299;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
        `;

        // 简易Cookie按钮
        const simpleButton = document.createElement('button');
        simpleButton.textContent = '简易获取';
        simpleButton.style.cssText = `
            padding: 8px 16px;
            background: #00a1d6;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
        `;

        // 新增:指定Cookie按钮
        const specifiedButton = document.createElement('button');
        specifiedButton.textContent = '获取完整Cookie';
        specifiedButton.style.cssText = `
            padding: 8px 16px;
            background: #6c757d;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
        `;

        // 添加点击事件
        fullButton.onclick = function() {
            const cookies = formatCookies(document.cookie);
            GM_setClipboard(cookies);
            showNotification('完整Cookie已复制到剪贴板');
            console.log('完整Cookies:\n', cookies);
        };

        simpleButton.onclick = function() {
            const cookies = getImportantCookies(document.cookie);
            GM_setClipboard(cookies);
            showNotification('重要Cookie已复制到剪贴板');
            console.log('要Cookies:\n', cookies);
        };

        specifiedButton.onclick = async function() {
            try {
                specifiedButton.disabled = true;
                specifiedButton.textContent = '获取中...';

                const cookies = await getSpecifiedCookie();
                if (cookies) {
                    GM_setClipboard(cookies);
                    showNotification(`Cookie已复制 (${cookies.length}字符)\n包含 ${cookies.split(';').length} 个cookie`);
                    console.log('获取的Cookie字符串:\n', cookies);
                    console.log(`字符串长度: ${cookies.length}`);
                }
            } catch (error) {
                showNotification('获取Cookie失败: ' + error.message);
                console.error('获取Cookie失败:', error);
            } finally {
                specifiedButton.disabled = false;
                specifiedButton.textContent = '获取完整Cookie';
            }
        };

        container.appendChild(fullButton);
        container.appendChild(simpleButton);
        container.appendChild(specifiedButton);
        document.body.appendChild(container);
    }

    // 添加错误处理函数
    function handleError(error, context) {
        console.error(`[Cookie Getter] ${context}:`, error);
        return null;
    }

    // 修改按钮添加逻辑
    function addButtonsWhenReady() {
        if (!document.body) {
            setTimeout(addButtonsWhenReady, 100);
            return;
        }

        try {
            addButtons();
        } catch (error) {
            handleError(error, '添加按钮失败');
        }
    }

    // 修改初始化调用
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', addButtonsWhenReady);
    } else {
        addButtonsWhenReady();
    }

    // 添加页面错误监听
    window.addEventListener('error', function(event) {
        handleError(event.error, '页面错误');
    });

    // 添加未处理的Promise错误监听
    window.addEventListener('unhandledrejection', function(event) {
        handleError(event.reason, '未处理的Promise错误');
    });
})();