// ==UserScript== // @name Cookie获取助手 // @namespace http://tampermonkey.net/ // @version 2.3.0 // @description 帮助新手用户获取网站Cookie,仅用于学习和个人使用 // @author Your Name // @match *://*/* // @match about:blank // @match about:newtab // @grant GM_setClipboard // @grant GM_notification // @grant GM_openInTab // @grant GM_cookie // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @run-at document-end // @antifeature ads 验证后免费使用24小时,需扫码观看广告获取验证码 // ==/UserScript== (function() { 'use strict'; // ========== 验证码验证模块 ========== const VERIFY_CONFIG = { API_URL: 'https://qsy.iano.cn/api/code/verify', QRCODE_IMG: 'https://qsy.iano.cn/yzm.png', STORAGE_VALID_UNTIL: 'cookie_helper_valid_until', STORAGE_FREE_USED: 'cookie_helper_free_used', STORAGE_USE_COUNT: 'cookie_helper_use_count' }; // 检查是否已验证(24小时有效期内) function isVerified() { const validUntil = GM_getValue(VERIFY_CONFIG.STORAGE_VALID_UNTIL, 0); return validUntil > Date.now() / 1000; } // 检查是否已用过免费次数 function hasUsedFreeTrial() { return GM_getValue(VERIFY_CONFIG.STORAGE_FREE_USED, false); } // 获取使用次数 function getUseCount() { return GM_getValue(VERIFY_CONFIG.STORAGE_USE_COUNT, 0); } // 记录一次使用 function recordUse() { const count = getUseCount() + 1; GM_setValue(VERIFY_CONFIG.STORAGE_USE_COUNT, count); if (count >= 1) { GM_setValue(VERIFY_CONFIG.STORAGE_FREE_USED, true); } } // 是否需要验证(用过免费次数且不在有效期内) function needsVerification() { return hasUsedFreeTrial() && !isVerified(); } // Cookie打码(显示前30%,后面用*替代) function maskCookie(cookieStr) { if (!cookieStr) return ''; const parts = cookieStr.split('; '); const showCount = Math.max(1, Math.ceil(parts.length * 0.3)); const visible = parts.slice(0, showCount).join('; '); const hiddenCount = parts.length - showCount; return visible + '; ' + '●'.repeat(20) + `\n\n🔒 还有 ${hiddenCount} 个Cookie字段已隐藏,验证后查看完整内容`; } // 验证验证码 function verifyCode(code, onSuccess, onError) { GM_xmlhttpRequest({ method: 'POST', url: VERIFY_CONFIG.API_URL, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: 'code=' + encodeURIComponent(code), onload: function(res) { try { const data = JSON.parse(res.responseText); if (data.code === 1 && data.data.valid) { GM_setValue(VERIFY_CONFIG.STORAGE_VALID_UNTIL, data.data.valid_until); onSuccess(data); } else { onError(data.msg || '验证码无效或已过期'); } } catch(e) { onError('验证失败,请重试'); } }, onerror: function() { onError('网络错误,请重试'); } }); } // 显示验证弹窗 function showVerifyDialog(onVerified) { // 如果已存在就不重复创建 if (document.getElementById('ch-verify-overlay')) return; const overlay = document.createElement('div'); overlay.id = 'ch-verify-overlay'; overlay.innerHTML = `
🔐 验证后继续使用
扫码观看广告获取验证码
验证后 24 小时内免费使用全部功能
扫码获取验证码
`; document.body.appendChild(overlay); const input = document.getElementById('ch-vfy-code'); const btn = document.getElementById('ch-vfy-submit'); const errEl = document.getElementById('ch-vfy-err'); const closeBtn = document.getElementById('ch-vfy-close'); closeBtn.onclick = () => overlay.remove(); overlay.onclick = (e) => { if (e.target === overlay) overlay.remove(); }; btn.onclick = function() { const code = input.value.trim(); if (!code || code.length < 4) { errEl.textContent = '请输入4位验证码'; errEl.style.display = 'block'; return; } btn.disabled = true; btn.textContent = '验证中...'; errEl.style.display = 'none'; verifyCode(code, function() { overlay.remove(); if (typeof GM_notification !== 'undefined') { GM_notification({ text: '✅ 验证成功!24小时内免费使用', timeout: 3000 }); } if (onVerified) onVerified(); }, function(msg) { errEl.textContent = msg; errEl.style.display = 'block'; btn.disabled = false; btn.textContent = '验 证'; } ); }; input.onkeypress = (e) => { if (e.key === 'Enter') btn.click(); }; setTimeout(() => input.focus(), 100); } // 需要验证时的通用拦截(返回true表示被拦截了) function requireVerification(action, callback) { if (isVerified()) return false; if (!hasUsedFreeTrial()) return false; // 还有免费次数,不拦截 showVerifyDialog(callback); return true; } // ========== 验证码验证模块结束 ========== // 免责声明 const DISCLAIMER = ` 【免责声明】 本脚本仅用于学习和个人使用目的,帮助不熟悉技术的用户了解Cookie的获取方式。 - 本脚本不会存储、上传或泄露任何用户数据 - 所有Cookie信息仅在本地显示,不会发送到任何服务器 - 请勿将本脚本用于任何违法违规行为 - 使用本脚本即表示您同意自行承担使用风险 - 请遵守相关网站的服务条款和法律法规 `.trim(); // 平台配置 const PLATFORMS = { xiaohongshu: { name: '小红书', domain: 'xiaohongshu.com', url: 'https://www.xiaohongshu.com', checkLogin: checkXiaohongshuLogin, getCookie: getXiaohongshuCookie, verifyCookie: verifyXiaohongshuCookie, icon: '📕' }, zhihu: { name: '知乎', domain: 'zhihu.com', url: 'https://www.zhihu.com', checkLogin: checkZhihuLogin, getCookie: getZhihuCookie, verifyCookie: verifyZhihuCookie, icon: '🔵' }, douyin: { name: '抖音', domain: 'douyin.com', url: 'https://www.douyin.com', checkLogin: checkDouyinLogin, getCookie: getDouyinCookie, verifyCookie: verifyDouyinCookie, icon: '🎵' }, iqiyi: { name: '爱奇艺', domain: 'iqiyi.com', url: 'https://www.iqiyi.com', checkLogin: checkIqiyiLogin, getCookie: getIqiyiCookie, verifyCookie: verifyIqiyiCookie, icon: '🎬' }, tencent: { name: '腾讯视频', domain: 'v.qq.com', url: 'https://v.qq.com', checkLogin: checkTencentLogin, getCookie: getTencentCookie, verifyCookie: verifyTencentCookie, icon: '🎥' }, weibo: { name: '微博', domain: 'weibo.com', url: 'https://www.weibo.com', checkLogin: checkWeiboLogin, getCookie: getWeiboCookie, verifyCookie: verifyWeiboCookie, icon: '🔴' }, bilibili: { name: 'B站', domain: 'bilibili.com', url: 'https://www.bilibili.com', checkLogin: checkBilibiliLogin, getCookie: getBilibiliCookie, verifyCookie: verifyBilibiliCookie, icon: '📺' }, taobao: { name: '淘宝', domain: 'taobao.com', url: 'https://www.taobao.com', checkLogin: checkTaobaoLogin, getCookie: getTaobaoCookie, verifyCookie: verifyTaobaoCookie, icon: '🛒' }, jd: { name: '京东', domain: 'jd.com', url: 'https://www.jd.com', checkLogin: checkJdLogin, getCookie: getJdCookie, verifyCookie: verifyJdCookie, icon: '🐕' }, netease_music: { name: '网易云音乐', domain: 'music.163.com', url: 'https://music.163.com', checkLogin: checkNeteaseMusicLogin, getCookie: getNeteaseMusicCookie, verifyCookie: verifyNeteaseMusicCookie, icon: '🎶' }, weread: { name: '微信读书', domain: 'weread.qq.com', url: 'https://weread.qq.com', checkLogin: checkWereadLogin, getCookie: getWereadCookie, verifyCookie: verifyWereadCookie, icon: '📖' } }; // 检测当前平台 function getCurrentPlatform() { const hostname = window.location.hostname; for (const [key, platform] of Object.entries(PLATFORMS)) { if (hostname.includes(platform.domain)) { return key; } } return null; } // 小红书登录检测(多重检测,提高准确性) async function checkXiaohongshuLogin() { console.log('[Cookie助手] 开始检测登录状态...'); // 方法1: 检查Cookie中是否有登录标识(最快速的判断) const cookies = document.cookie; const hasLoginCookie = cookies.includes('web_session=') || cookies.includes('a1=') || cookies.includes('customer-sso-sid='); console.log('[Cookie助手] Cookie登录标识:', hasLoginCookie); // 方法2: 检查是否有登录按钮(未登录才有) const loginButtons = document.querySelectorAll('button, a, span, div'); let hasLoginButton = false; for (const btn of loginButtons) { const text = btn.textContent.trim(); if ((text === '登录' || text === '注册' || text === '登录 / 注册' || text === '登录/注册') && btn.offsetParent !== null) { hasLoginButton = true; console.log('[Cookie助手] 发现登录按钮:', text); break; } } if (hasLoginButton && !hasLoginCookie) { console.log('[Cookie助手] 登录状态: false (发现登录按钮且无登录Cookie)'); return false; } // 方法3: 检查是否在个人主页 const isUserPage = window.location.pathname.includes('/user/profile') || window.location.pathname.includes('/user/self'); if (isUserPage) { console.log('[Cookie助手] 登录状态: true (在个人主页)'); return true; } // 方法4: 检查页面标题和内容 const pageTitle = document.title; const bodyText = document.body ? document.body.textContent : ''; if (bodyText.includes('登录后推荐更懂你的笔记') || bodyText.includes('扫码登录') || pageTitle.includes('登录')) { console.log('[Cookie助手] 登录状态: false (页面提示登录)'); return false; } // 方法5: 检查是否有用户相关元素 const userSelectors = [ '[class*="user-card"]', '[class*="UserCard"]', '[class*="sidebar"] [class*="avatar"]', '.user .avatar', '[class*="user-info"] [class*="name"]' ]; const hasUserElements = userSelectors.some(sel => document.querySelector(sel) !== null); const hasLoginBtnElement = document.querySelector('[class*="login-btn"]') !== null; const isLoggedIn = hasLoginCookie || (hasUserElements && !hasLoginBtnElement); console.log('[Cookie助手] 登录状态:', isLoggedIn, `(Cookie:${hasLoginCookie}, 用户元素:${hasUserElements})`); return isLoggedIn; } // 获取小红书Cookie(多域名覆盖,确保完整性) async function getXiaohongshuCookie() { const allCookies = new Map(); // 方法1: GM_cookie API 多域名获取 if (typeof GM_cookie !== 'undefined') { const domains = [ '.xiaohongshu.com', 'www.xiaohongshu.com', 'edith.xiaohongshu.com', '.xhscdn.com' ]; for (const domain of domains) { try { const cookies = await new Promise((resolve, reject) => { GM_cookie.list({ domain }, (cookies, error) => { if (error) reject(error); else resolve(cookies || []); }); }); for (const c of cookies) { const existing = allCookies.get(c.name); if (!existing || (c.value && c.value.length > (existing.length || 0))) { allCookies.set(c.name, c.value); } } } catch (error) { console.log(`[Cookie助手] 获取域名 ${domain} Cookie失败:`, error); } } // 也尝试用url方式获取 try { const cookies = await new Promise((resolve, reject) => { GM_cookie.list({ url: 'https://www.xiaohongshu.com' }, (cookies, error) => { if (error) reject(error); else resolve(cookies || []); }); }); for (const c of cookies) { if (!allCookies.has(c.name)) { allCookies.set(c.name, c.value); } } } catch (e) { /* 忽略 */ } } // 方法2: 补充document.cookie if (document.cookie) { for (const pair of document.cookie.split(';')) { const eqIdx = pair.indexOf('='); if (eqIdx > 0) { const name = pair.substring(0, eqIdx).trim(); const value = pair.substring(eqIdx + 1).trim(); if (name && !allCookies.has(name)) { allCookies.set(name, value); } } } } if (allCookies.size === 0) return null; // 关键Cookie优先排序 const priorityKeys = [ 'web_session', 'a1', 'webId', 'id_token', 'acw_tc', 'xsecappid', 'websectiga', 'sec_poison_id', 'customer-sso-sid' ]; const sorted = []; for (const key of priorityKeys) { if (allCookies.has(key)) { sorted.push([key, allCookies.get(key)]); allCookies.delete(key); } } for (const [key, value] of allCookies) { sorted.push([key, value]); } return sorted.map(([k, v]) => `${k}=${v}`).join('; '); } // 检查Cookie是否完整(多平台分级检测) function checkCookieComplete(cookies) { // 根据当前平台选择检测规则 const platform = getCurrentPlatform(); const rules = { xiaohongshu: { critical: ['web_session', 'a1', 'webId'], important: ['xsecappid', 'websectiga', 'sec_poison_id'], core: ['web_session', 'a1'] }, zhihu: { critical: ['z_c0', 'd_c0'], important: ['_xsrf', '_zap'], core: ['z_c0'] }, douyin: { critical: ['sessionid', 'ttwid'], important: ['msToken', 's_v_web_id', 'passport_csrf_token'], core: ['sessionid'] }, iqiyi: { critical: ['P00001', 'P00003'], important: ['QC005', 'QC006'], core: ['P00001'] }, tencent: { critical: ['login_type', 'vqq_access_token'], important: ['vqq_vuserid', 'vqq_vusession'], core: ['login_type', 'vqq_access_token'] }, weibo: { critical: ['SUB', 'SUBP'], important: ['SINAGLOBAL', '_s_tentry'], core: ['SUB'] }, bilibili: { critical: ['SESSDATA', 'bili_jct'], important: ['DedeUserID', 'sid'], core: ['SESSDATA'] }, taobao: { critical: ['_m_h5_tk', '_m_h5_tk_enc'], important: ['cookie2', 'sgcookie', 't'], core: ['_m_h5_tk'] }, jd: { critical: ['pt_key', 'pt_pin'], important: ['pwdt_id', 'sfstoken'], core: ['pt_key', 'pt_pin'] }, netease_music: { critical: ['MUSIC_U'], important: ['__csrf', 'NMTID'], core: ['MUSIC_U'] }, weread: { critical: ['wr_skey'], important: ['wr_name', 'wr_avatar', 'wr_vid'], core: ['wr_skey'] } }; const rule = rules[platform] || rules.xiaohongshu; const missingCritical = rule.critical.filter(f => !cookies.includes(f + '=')); const missingImportant = rule.important.filter(f => !cookies.includes(f + '=')); const hasCoreSession = rule.core.some(f => cookies.includes(f + '=')); return { complete: hasCoreSession && missingCritical.length === 0 && missingImportant.length === 0, usable: hasCoreSession, missing: [...missingCritical, ...missingImportant], summary: hasCoreSession ? (missingCritical.length === 0 && missingImportant.length === 0 ? '✅ Cookie完整' : `⚠️ 缺少${missingCritical.length + missingImportant.length}个重要字段: ${[...missingCritical, ...missingImportant].join(', ')}`) : `❌ 缺少核心登录Cookie (${rule.core.join('/')})` }; } // 验证小红书Cookie有效性(通过设置Cookie并测试登录) async function verifyXiaohongshuCookie() { try { // 方法1: 尝试调用用户信息API const response = await fetch('https://edith.xiaohongshu.com/api/sns/web/v1/user/selfinfo', { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Referer': 'https://www.xiaohongshu.com/', 'User-Agent': navigator.userAgent, 'X-Requested-With': 'XMLHttpRequest' } }); if (response.status === 406) { // 如果遇到406,使用备用验证方法:检查页面元素 return verifyByPageContent(); } if (!response.ok) { return { valid: false, message: `请求失败 (${response.status})`, details: '无法连接到服务器或Cookie已失效' }; } const data = await response.json(); // 检查返回数据 if (data.success && data.data) { return { valid: true, message: 'Cookie有效', details: `用户: ${data.data.nickname || data.data.red_id || '已登录用户'}`, userData: data.data }; } else { return { valid: false, message: 'Cookie无效或已过期', details: data.msg || '请重新登录' }; } } catch (error) { // 如果API调用失败,尝试备用方法 return verifyByPageContent(); } } // 通过设置Cookie并测试登录来验证 async function testLoginWithCookie(cookieString) { if (typeof GM_cookie === 'undefined') { return { valid: false, message: '不支持Cookie登录测试', details: '您的油猴管理器不支持GM_cookie API,请使用Tampermonkey或Violentmonkey' }; } try { // 解析Cookie字符串(用indexOf避免值中含=被截断) const cookieMap = {}; cookieString.split(';').forEach(pair => { const eqIdx = pair.indexOf('='); if (eqIdx > 0) { const name = pair.substring(0, eqIdx).trim(); const value = pair.substring(eqIdx + 1).trim(); if (name) cookieMap[name] = value; } }); const httpOnlyCookies = new Set([ 'web_session', 'id_token', 'acw_tc', 'customer-sso-sid', 'z_c0', 'sessionid', 'sessionid_ss', 'P00001', 'SUB', 'SUBP', 'SESSDATA', 'pt_key', 'MUSIC_U', 'wr_skey' ]); let setCount = 0; let failedCookies = []; // 根据当前平台确定Cookie设置URL const platform = getCurrentPlatform(); const platformConfig = platform ? PLATFORMS[platform] : null; const cookieUrl = platformConfig ? platformConfig.url : window.location.origin; // 设置所有解析到的Cookie for (const [name, value] of Object.entries(cookieMap)) { try { await new Promise((resolve) => { GM_cookie.set({ name: name, value: value, url: cookieUrl, path: '/', secure: true, httpOnly: httpOnlyCookies.has(name) }, (error) => { if (error) { console.log(`[Cookie助手] 设置Cookie ${name} 失败:`, error); failedCookies.push(name); } else { setCount++; } resolve(); }); }); } catch (e) { failedCookies.push(name); } } console.log(`成功设置 ${setCount} 个Cookie,失败 ${failedCookies.length} 个`); if (failedCookies.length > 0) { console.log('失败的Cookie:', failedCookies.join(', ')); } if (setCount === 0) { return { valid: false, message: 'Cookie设置失败', details: '未找到关键Cookie字段或全部设置失败。请确保Cookie格式正确。' }; } // 等待Cookie设置生效 await new Promise(resolve => setTimeout(resolve, 1000)); // 使用平台的验证方法 if (platformConfig && platformConfig.verifyCookie) { try { const verifyResult = await platformConfig.verifyCookie(); if (verifyResult.valid) { return { valid: true, message: '✅ Cookie有效!登录测试成功', details: `已成功设置${setCount}个Cookie。${verifyResult.details || ''}。页面将在3秒后刷新。`, userData: verifyResult.userData, needRefresh: true }; } } catch (e) { console.log('[Cookie助手] 平台验证失败,尝试通用验证'); } } // 通用验证:刷新页面确认 return { valid: true, message: '✅ Cookie已设置!', details: `已成功设置${setCount}个Cookie(失败${failedCookies.length}个)。页面将在3秒后刷新以确认登录状态。`, needRefresh: true }; } catch (error) { console.error('登录测试错误:', error); return { valid: false, message: '登录测试失败', details: error.message || '发生未知错误' }; } } // ========== 通用Cookie获取辅助函数 ========== async function getPlatformCookies(domain, subDomains) { const allCookies = new Map(); if (typeof GM_cookie !== 'undefined') { const domains = [domain, ...subDomains]; for (const d of domains) { try { const cookies = await new Promise((resolve, reject) => { GM_cookie.list({ domain: d }, (cookies, error) => { if (error) reject(error); else resolve(cookies || []); }); }); for (const c of cookies) { const existing = allCookies.get(c.name); if (!existing || (c.value && c.value.length > (existing.length || 0))) { allCookies.set(c.name, c.value); } } } catch (e) { /* 忽略 */ } } } if (document.cookie) { for (const pair of document.cookie.split(';')) { const eqIdx = pair.indexOf('='); if (eqIdx > 0) { const name = pair.substring(0, eqIdx).trim(); const value = pair.substring(eqIdx + 1).trim(); if (name && !allCookies.has(name)) { allCookies.set(name, value); } } } } return allCookies; } function cookieMapToString(cookieMap, priorityKeys) { const sorted = []; for (const key of (priorityKeys || [])) { if (cookieMap.has(key)) { sorted.push([key, cookieMap.get(key)]); cookieMap.delete(key); } } for (const [key, value] of cookieMap) { sorted.push([key, value]); } return sorted.length > 0 ? sorted.map(([k, v]) => `${k}=${v}`).join('; ') : null; } // ========== 知乎 ========== async function checkZhihuLogin() { console.log('[Cookie助手] 检测知乎登录状态...'); const cookies = document.cookie; if (cookies.includes('z_c0=')) { console.log('[Cookie助手] 知乎: 发现z_c0 Cookie,已登录'); return true; } const loginBtn = document.querySelector('[class*="SignContainer"]') || document.querySelector('button[class*="login"]') || document.querySelector('.AppHeader-login'); if (loginBtn && loginBtn.offsetParent !== null) { return false; } const userAvatar = document.querySelector('.AppHeader-profileAvatar') || document.querySelector('[class*="Avatar"][class*="UserLink"]') || document.querySelector('.TopstoryContainer [class*="avatar"]'); return !!userAvatar; } async function getZhihuCookie() { const allCookies = await getPlatformCookies('.zhihu.com', [ 'www.zhihu.com', 'zhuanlan.zhihu.com' ]); return cookieMapToString(allCookies, [ 'z_c0', 'd_c0', '_zap', '_xsrf', 'KLBRSID', 'SESSIONID', 'BEC', 'JOID', 'osd' ]); } async function verifyZhihuCookie() { try { const response = await fetch('https://www.zhihu.com/api/v4/me', { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json', 'Referer': 'https://www.zhihu.com/', } }); if (response.ok) { const data = await response.json(); if (data.name || data.id) { return { valid: true, message: 'Cookie有效', details: `用户: ${data.name || data.id}`, userData: data }; } } if (response.status === 401) { return { valid: false, message: 'Cookie无效或已过期', details: '请重新登录知乎' }; } return verifyByPageContent(); } catch (error) { return verifyByPageContent(); } } // ========== 抖音 ========== async function checkDouyinLogin() { console.log('[Cookie助手] 检测抖音登录状态...'); const cookies = document.cookie; if (cookies.includes('sessionid=') || cookies.includes('passport_csrf_token=')) { const hasSession = cookies.includes('sessionid=') && !cookies.includes('sessionid=;') && !cookies.includes('sessionid=""'); if (hasSession) { console.log('[Cookie助手] 抖音: 发现sessionid,已登录'); return true; } } const loginBtn = document.querySelector('[class*="login-btn"]') || document.querySelector('[class*="LoginBtn"]') || document.querySelector('button[class*="login"]'); if (loginBtn && loginBtn.offsetParent !== null) { return false; } const userAvatar = document.querySelector('[class*="avatar"][class*="header"]') || document.querySelector('[class*="userAvatar"]') || document.querySelector('.semi-avatar'); return !!userAvatar; } async function getDouyinCookie() { const allCookies = await getPlatformCookies('.douyin.com', [ 'www.douyin.com', 'sso.douyin.com' ]); return cookieMapToString(allCookies, [ 'sessionid', 'sessionid_ss', 'sid_guard', 'uid_tt', 'uid_tt_ss', 'sid_tt', 'passport_csrf_token', 'ttwid', 'msToken', 's_v_web_id', 'odin_tt', 'passport_auth_status' ]); } async function verifyDouyinCookie() { try { const response = await fetch('https://www.douyin.com/aweme/v1/web/query/user/', { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json', 'Referer': 'https://www.douyin.com/', } }); if (response.ok) { const data = await response.json(); if (data.status_code === 0 || data.user_info) { return { valid: true, message: 'Cookie有效', details: '抖音登录状态正常' }; } } return verifyByPageContent(); } catch (error) { return verifyByPageContent(); } } // ========== 爱奇艺 ========== async function checkIqiyiLogin() { console.log('[Cookie助手] 检测爱奇艺登录状态...'); const cookies = document.cookie; if (cookies.includes('P00001=') || cookies.includes('P00003=')) { console.log('[Cookie助手] 爱奇艺: 发现登录Cookie'); return true; } const loginBtn = document.querySelector('[class*="login-btn"]') || document.querySelector('.header-login-btn') || document.querySelector('a[href*="passport.iqiyi.com"]'); if (loginBtn && loginBtn.offsetParent !== null) { return false; } const userEl = document.querySelector('[class*="header-user"]') || document.querySelector('[class*="user-avatar"]') || document.querySelector('.qy-header-vip'); return !!userEl; } async function getIqiyiCookie() { const allCookies = await getPlatformCookies('.iqiyi.com', [ 'www.iqiyi.com', 'passport.iqiyi.com' ]); return cookieMapToString(allCookies, [ 'P00001', 'P00002', 'P00003', 'P00004', 'QC005', 'QC006', 'QC007', 'QC008', 'T00404', '__dfp', 'IqiyiGUID' ]); } async function verifyIqiyiCookie() { try { const response = await fetch('https://passport.iqiyi.com/apis/user/info.action', { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json', 'Referer': 'https://www.iqiyi.com/', } }); if (response.ok) { const data = await response.json(); if (data.code === 'A00000' && data.data) { const nickname = data.data.nickname || data.data.name || '已登录用户'; return { valid: true, message: 'Cookie有效', details: `用户: ${nickname}`, userData: data.data }; } } return verifyByPageContent(); } catch (error) { return verifyByPageContent(); } } // ========== 腾讯视频 ========== async function checkTencentLogin() { console.log('[Cookie助手] 检测腾讯视频登录状态...'); const cookies = document.cookie; if (cookies.includes('login_type=') || cookies.includes('vqq_access_token=') || cookies.includes('uid=')) { console.log('[Cookie助手] 腾讯视频: 发现登录Cookie'); return true; } const loginBtn = document.querySelector('[class*="login_btn"]') || document.querySelector('.quick_login') || document.querySelector('a[href*="access.video.qq.com"]'); if (loginBtn && loginBtn.offsetParent !== null) { return false; } const userEl = document.querySelector('[class*="user_head"]') || document.querySelector('[class*="header_avatar"]') || document.querySelector('.mod_head_user .head_avatar'); return !!userEl; } async function getTencentCookie() { const allCookies = await getPlatformCookies('.qq.com', [ 'v.qq.com', '.video.qq.com', 'access.video.qq.com' ]); return cookieMapToString(allCookies, [ 'login_type', 'vqq_access_token', 'vqq_appid', 'vqq_openid', 'vqq_vuserid', 'vqq_vusession', 'uid', 'main_login', 'video_guid', 'video_platform', 'pgv_pvid' ]); } async function verifyTencentCookie() { try { const response = await fetch('https://access.video.qq.com/user/auth_refresh', { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json', 'Referer': 'https://v.qq.com/', } }); if (response.ok) { const data = await response.json(); if (data.ret === 0 || data.errcode === 0) { return { valid: true, message: 'Cookie有效', details: '腾讯视频登录状态正常' }; } } return verifyByPageContent(); } catch (error) { return verifyByPageContent(); } } // ========== 微博 ========== async function checkWeiboLogin() { console.log('[Cookie助手] 检测微博登录状态...'); const cookies = document.cookie; if (cookies.includes('SUB=') && !cookies.includes('SUB=_2A')) { return true; } if (cookies.includes('SUB=')) return true; const loginBtn = document.querySelector('[class*="LoginBtn"]') || document.querySelector('[node-type="loginBtn"]') || document.querySelector('a[href*="login.sina.com"]'); if (loginBtn && loginBtn.offsetParent !== null) return false; const userEl = document.querySelector('[class*="gn_name"]') || document.querySelector('[class*="head_portrait"]') || document.querySelector('.woo-avatar-img'); return !!userEl; } async function getWeiboCookie() { const allCookies = await getPlatformCookies('.weibo.com', [ 'www.weibo.com', 'weibo.com', 'passport.weibo.com', 's.weibo.com' ]); return cookieMapToString(allCookies, [ 'SUB', 'SUBP', 'SINAGLOBAL', '_s_tentry', 'UB', 'Apache', 'ULV', 'XSRF-TOKEN', 'WBPSESS', 'SCF' ]); } async function verifyWeiboCookie() { try { const response = await fetch('https://www.weibo.com/ajax/profile/info', { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json', 'Referer': 'https://www.weibo.com/' } }); if (response.ok) { const data = await response.json(); if (data.ok === 1 && data.data && data.data.user) { return { valid: true, message: 'Cookie有效', details: `用户: ${data.data.user.screen_name || '已登录'}`, userData: data.data.user }; } } return verifyByPageContent(); } catch (e) { return verifyByPageContent(); } } // ========== B站 ========== async function checkBilibiliLogin() { console.log('[Cookie助手] 检测B站登录状态...'); const cookies = document.cookie; if (cookies.includes('SESSDATA=') || cookies.includes('DedeUserID=')) { return true; } const loginBtn = document.querySelector('.header-login-entry') || document.querySelector('[class*="login-btn"]') || document.querySelector('.bili-header__entry--login'); if (loginBtn && loginBtn.offsetParent !== null) return false; const userEl = document.querySelector('.header-entry-avatar') || document.querySelector('.bili-header__entry--avatar') || document.querySelector('.header-entry-mini'); return !!userEl; } async function getBilibiliCookie() { const allCookies = await getPlatformCookies('.bilibili.com', [ 'www.bilibili.com', 'api.bilibili.com', 'passport.bilibili.com' ]); return cookieMapToString(allCookies, [ 'SESSDATA', 'bili_jct', 'DedeUserID', 'DedeUserID__ckMd5', 'sid', 'buvid3', 'buvid4', 'b_nut', 'b_lsid', 'buvid_fp', 'innersign', 'i-wanna-go-back' ]); } async function verifyBilibiliCookie() { try { const response = await fetch('https://api.bilibili.com/x/web-interface/nav', { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json', 'Referer': 'https://www.bilibili.com/' } }); if (response.ok) { const data = await response.json(); if (data.code === 0 && data.data && data.data.isLogin) { return { valid: true, message: 'Cookie有效', details: `用户: ${data.data.uname || 'UID:' + data.data.mid}`, userData: data.data }; } } return verifyByPageContent(); } catch (e) { return verifyByPageContent(); } } // ========== 淘宝 ========== async function checkTaobaoLogin() { console.log('[Cookie助手] 检测淘宝登录状态...'); const cookies = document.cookie; if (cookies.includes('_m_h5_tk=') || cookies.includes('cookie2=')) { return true; } const loginBtn = document.querySelector('[class*="site-nav-login"]') || document.querySelector('a[href*="login.taobao.com"]') || document.querySelector('.site-nav-sign'); if (loginBtn && loginBtn.offsetParent !== null) return false; const userEl = document.querySelector('[class*="site-nav-user"]') || document.querySelector('.site-nav-menu-hd'); return !!userEl; } async function getTaobaoCookie() { const allCookies = await getPlatformCookies('.taobao.com', [ 'www.taobao.com', 'login.taobao.com', 'h5api.m.taobao.com' ]); return cookieMapToString(allCookies, [ '_m_h5_tk', '_m_h5_tk_enc', 'cookie2', 'sgcookie', 't', '_tb_token_', 'unb', 'uc3', 'csg', 'skt', 'existShop', 'dnk', 'tracknick', 'lid', 'enc' ]); } async function verifyTaobaoCookie() { try { const cookies = document.cookie; const hasCore = cookies.includes('_m_h5_tk=') || cookies.includes('cookie2=') || cookies.includes('unb='); if (hasCore) { const nick = document.querySelector('[class*="site-nav-user"]'); if (nick) { return { valid: true, message: 'Cookie有效', details: `用户: ${nick.textContent.trim() || '已登录'}` }; } return { valid: true, message: 'Cookie可能有效', details: '检测到核心登录Cookie,建议在淘宝页面确认。' }; } return verifyByPageContent(); } catch (e) { return verifyByPageContent(); } } // ========== 京东 ========== async function checkJdLogin() { console.log('[Cookie助手] 检测京东登录状态...'); const cookies = document.cookie; if (cookies.includes('pt_key=') && cookies.includes('pt_pin=')) { return true; } const loginBtn = document.querySelector('.link-login') || document.querySelector('a[href*="passport.jd.com"]') || document.querySelector('[class*="login"]'); if (loginBtn && loginBtn.textContent.includes('登录') && loginBtn.offsetParent !== null) return false; const userEl = document.querySelector('.nickname') || document.querySelector('[class*="user-name"]') || document.querySelector('.nav-user-info'); return !!userEl; } async function getJdCookie() { const allCookies = await getPlatformCookies('.jd.com', [ 'www.jd.com', 'passport.jd.com', 'api.m.jd.com', 'plogin.m.jd.com' ]); return cookieMapToString(allCookies, [ 'pt_key', 'pt_pin', 'pt_token', 'pwdt_id', 'sfstoken', 'sid', 'thor', '__jdu', 'unick', 'pin', 'TrackID', 'pinId', 'areaId' ]); } async function verifyJdCookie() { try { const cookies = document.cookie; const hasKey = cookies.includes('pt_key='); const hasPin = cookies.includes('pt_pin='); if (hasKey && hasPin) { return { valid: true, message: 'Cookie有效', details: '检测到pt_key和pt_pin,京东登录状态正常。' }; } if (hasKey || hasPin) { return { valid: true, message: 'Cookie部分有效', details: '检测到部分登录Cookie,建议在京东页面确认。' }; } return verifyByPageContent(); } catch (e) { return verifyByPageContent(); } } // ========== 网易云音乐 ========== async function checkNeteaseMusicLogin() { console.log('[Cookie助手] 检测网易云音乐登录状态...'); const cookies = document.cookie; if (cookies.includes('MUSIC_U=')) { return true; } const loginBtn = document.querySelector('[class*="login"]') || document.querySelector('.link-login') || document.querySelector('a[href*="login"]'); if (loginBtn && loginBtn.textContent.includes('登录') && loginBtn.offsetParent !== null) return false; const userEl = document.querySelector('[class*="user-info"]') || document.querySelector('.head_portrait') || document.querySelector('.m-user-avatar'); return !!userEl; } async function getNeteaseMusicCookie() { const allCookies = await getPlatformCookies('.163.com', [ 'music.163.com', '.music.163.com' ]); return cookieMapToString(allCookies, [ 'MUSIC_U', '__csrf', 'NMTID', 'JSESSIONID-WYYY', '_iuqxldmzr_', '_ntes_nnid', '_ntes_nuid', 'WEVNSM', 'WNMCID', 'ntes_kaola_ad' ]); } async function verifyNeteaseMusicCookie() { try { const cookies = document.cookie; if (cookies.includes('MUSIC_U=')) { return { valid: true, message: 'Cookie有效', details: '检测到MUSIC_U,网易云音乐登录状态正常。' }; } return verifyByPageContent(); } catch (e) { return verifyByPageContent(); } } // ========== 微信读书 ========== async function checkWereadLogin() { console.log('[Cookie助手] 检测微信读书登录状态...'); const cookies = document.cookie; if (cookies.includes('wr_skey=') || cookies.includes('wr_vid=')) { return true; } const loginBtn = document.querySelector('[class*="navBar_link_Login"]') || document.querySelector('[class*="readerTopBar_login"]'); if (loginBtn && loginBtn.offsetParent !== null) return false; const userEl = document.querySelector('[class*="navBar_avatar"]') || document.querySelector('[class*="readerTopBar_avatar"]'); return !!userEl; } async function getWereadCookie() { const allCookies = await getPlatformCookies('.qq.com', [ 'weread.qq.com', '.weread.qq.com' ]); return cookieMapToString(allCookies, [ 'wr_skey', 'wr_vid', 'wr_name', 'wr_avatar', 'wr_rt', 'wr_localvid', 'wr_gender', 'wr_pf' ]); } async function verifyWereadCookie() { try { const response = await fetch('https://weread.qq.com/web/user?userVid=0', { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json', 'Referer': 'https://weread.qq.com/' } }); if (response.ok) { const data = await response.json(); if (data.name) { return { valid: true, message: 'Cookie有效', details: `用户: ${data.name}`, userData: data }; } } return verifyByPageContent(); } catch (e) { return verifyByPageContent(); } } // 备用验证方法:通过页面内容验证 function verifyByPageContent() { const cookies = document.cookie; const hasWebSession = cookies.includes('web_session='); const hasA1 = cookies.includes('a1='); const hasWebId = cookies.includes('webId='); const hasCoreLogin = hasWebSession || hasA1; if (!hasCoreLogin && !hasWebId) { return { valid: false, message: 'Cookie无效', details: '未找到任何小红书相关Cookie字段' }; } const userIndicators = [ '.avatar', '[class*="avatar"]', '[class*="Avatar"]', '.user-info', '[class*="user-name"]', '[class*="nickname"]' ]; const loginIndicators = [ '[class*="login-btn"]', '[class*="LoginBtn"]' ]; const hasUserElement = userIndicators.some(sel => document.querySelector(sel) !== null); const hasLoginBtn = loginIndicators.some(sel => document.querySelector(sel) !== null); if (hasUserElement && !hasLoginBtn && hasCoreLogin) { return { valid: true, message: 'Cookie有效', details: '检测到登录状态,Cookie包含核心字段。' }; } if (hasCoreLogin) { return { valid: true, message: 'Cookie可能有效', details: '已检测到核心登录Cookie,建议测试功能(如点赞)以确认。' }; } return { valid: false, message: 'Cookie可能无效', details: '缺少核心登录标识(web_session/a1),建议重新登录后获取。' }; } // 创建UI面板 function createPanel() { const panel = document.createElement('div'); panel.id = 'cookie-helper-panel'; panel.innerHTML = `
🍪 Cookie获取助手
⚠️ 免责声明(请先阅读)
${DISCLAIMER}
${Object.entries(PLATFORMS).map(([key, platform]) => `
${platform.icon} ${platform.name} ${platform.disabled ? '即将支持' : ''}
${!platform.disabled ? `` : ''}
`).join('')}
请选择一个平台
`; // 添加样式 const style = document.createElement('style'); style.textContent = ` #cookie-helper-panel { position: fixed; top: 50%; right: 20px; transform: translateY(-50%) scale(0.95); width: 370px; max-height: 80vh; background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-radius: 16px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.05); z-index: 999999; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; overflow: hidden; display: none; flex-direction: column; opacity: 0; transition: opacity 0.25s ease, transform 0.25s ease; } #cookie-helper-panel.ch-panel-open { opacity: 1; transform: translateY(-50%) scale(1); } .ch-header { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%); color: white; padding: 18px 20px; display: flex; justify-content: space-between; align-items: center; } .ch-title { font-size: 15px; font-weight: 700; letter-spacing: 0.3px; } .ch-close { background: rgba(255, 255, 255, 0.15); border: none; color: white; font-size: 20px; width: 30px; height: 30px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.2s, transform 0.15s; line-height: 1; } .ch-close:hover { background: rgba(255, 255, 255, 0.3); transform: rotate(90deg); } .ch-disclaimer { padding: 10px 20px; background: linear-gradient(135deg, #fef9c3 0%, #fef3c7 100%); border-bottom: 1px solid rgba(0, 0, 0, 0.06); } .ch-disclaimer details { cursor: pointer; } .ch-disclaimer summary { font-size: 12px; color: #92400e; font-weight: 500; user-select: none; } .ch-disclaimer pre { margin: 10px 0 0 0; font-size: 11px; color: #92400e; white-space: pre-wrap; line-height: 1.5; } .ch-platforms { padding: 14px 16px; border-bottom: 1px solid rgba(0, 0, 0, 0.06); max-height: 220px; overflow-y: auto; } .ch-platforms::-webkit-scrollbar { width: 4px; } .ch-platforms::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 4px; } .ch-platform-item { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; margin-bottom: 6px; background: rgba(0, 0, 0, 0.03); border-radius: 10px; cursor: pointer; transition: all 0.2s ease; border: 2px solid transparent; } .ch-platform-info { display: flex; align-items: center; flex: 1; } .ch-platform-item:hover:not(.disabled) { background: rgba(99, 102, 241, 0.06); transform: translateX(3px); } .ch-platform-item.active { background: rgba(99, 102, 241, 0.08); border-color: #6366f1; box-shadow: 0 0 0 1px rgba(99, 102, 241, 0.1); } .ch-platform-item.disabled { opacity: 0.45; cursor: not-allowed; } .ch-platform-test-btn { background: linear-gradient(135deg, #06b6d4, #0891b2); color: white; border: none; padding: 5px 12px; border-radius: 8px; font-size: 11px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .ch-platform-test-btn:hover { transform: scale(1.05); box-shadow: 0 2px 8px rgba(6, 182, 212, 0.3); } .ch-platform-test-btn:active { transform: scale(0.97); } .ch-platform-icon { font-size: 22px; margin-right: 10px; } .ch-platform-name { flex: 1; font-size: 13px; font-weight: 600; color: #1e293b; } .ch-badge { font-size: 10px; padding: 2px 8px; background: linear-gradient(135deg, #94a3b8, #64748b); color: white; border-radius: 10px; font-weight: 500; } .ch-content { padding: 18px; flex: 1; overflow-y: auto; } .ch-content::-webkit-scrollbar { width: 4px; } .ch-content::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.12); border-radius: 4px; } .ch-status { text-align: center; padding: 18px; color: #64748b; font-size: 13px; font-weight: 500; } .ch-status.success { color: #16a34a; } .ch-status.error { color: #dc2626; } .ch-actions { text-align: center; margin-top: 14px; display: flex; flex-direction: column; gap: 8px; } .ch-btn { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); color: white; border: none; padding: 11px 28px; border-radius: 10px; font-size: 13px; font-weight: 600; cursor: pointer; transition: transform 0.15s, box-shadow 0.2s; letter-spacing: 0.3px; } .ch-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(99, 102, 241, 0.35); } .ch-btn:active { transform: translateY(0); } .ch-btn:disabled { background: #94a3b8; cursor: not-allowed; transform: none; box-shadow: none; } .ch-btn-refresh { background: linear-gradient(135deg, #06b6d4, #0891b2); color: white; border: none; padding: 8px 16px; border-radius: 8px; font-size: 12px; font-weight: 600; cursor: pointer; transition: all 0.15s; } .ch-btn-refresh:hover { box-shadow: 0 2px 8px rgba(6, 182, 212, 0.3); } .ch-result { margin-top: 14px; } .ch-result-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-size: 12px; font-weight: 600; color: #475569; } .ch-btn-small { background: linear-gradient(135deg, #22c55e, #16a34a); color: white; border: none; padding: 5px 12px; border-radius: 8px; font-size: 11px; font-weight: 600; cursor: pointer; transition: all 0.15s; } .ch-btn-small:hover { box-shadow: 0 2px 8px rgba(34, 197, 94, 0.3); } .ch-cookie-text { width: 100%; min-height: 100px; max-height: 180px; padding: 10px 12px; border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 10px; font-size: 11px; font-family: 'SF Mono', 'Cascadia Code', 'Courier New', monospace; resize: vertical; background: rgba(0, 0, 0, 0.02); box-sizing: border-box; color: #334155; line-height: 1.5; transition: border-color 0.2s; } .ch-cookie-text:focus { outline: none; border-color: #6366f1; box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1); } .ch-cookie-stats { margin: 8px 0; padding: 8px 12px; background: linear-gradient(135deg, rgba(99, 102, 241, 0.06), rgba(139, 92, 246, 0.06)); border-radius: 8px; font-size: 11px; color: #475569; line-height: 1.5; border: 1px solid rgba(99, 102, 241, 0.1); } .ch-verify-section { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; } .ch-btn-verify { width: 100%; background: linear-gradient(135deg, #06b6d4, #0891b2); color: white; border: none; padding: 9px 16px; border-radius: 8px; font-size: 12px; font-weight: 600; cursor: pointer; transition: all 0.15s; } .ch-btn-verify:hover { box-shadow: 0 2px 10px rgba(6, 182, 212, 0.3); } .ch-btn-verify:disabled { background: #94a3b8; cursor: not-allowed; } .ch-btn-login-test { width: 100%; background: linear-gradient(135deg, #ec4899, #db2777); color: white; border: none; padding: 9px 16px; border-radius: 8px; font-size: 12px; font-weight: 600; cursor: pointer; transition: all 0.15s; } .ch-btn-login-test:hover { box-shadow: 0 2px 10px rgba(236, 72, 153, 0.3); } .ch-btn-login-test:disabled { background: #94a3b8; cursor: not-allowed; } .ch-test-section { margin-top: 10px; } .ch-btn-test { width: 100%; background: linear-gradient(135deg, #ec4899, #db2777); color: white; border: none; padding: 10px 16px; border-radius: 8px; font-size: 13px; font-weight: 600; cursor: pointer; transition: all 0.15s; margin-bottom: 6px; } .ch-btn-test:hover { box-shadow: 0 3px 12px rgba(236, 72, 153, 0.3); transform: translateY(-1px); } .ch-btn-test:disabled { background: #94a3b8; cursor: not-allowed; transform: none; box-shadow: none; } .ch-test-hint { font-size: 10px; color: #94a3b8; text-align: center; line-height: 1.4; } .ch-test-result { margin-top: 10px; padding: 10px 12px; border-radius: 8px; font-size: 12px; line-height: 1.5; } .ch-test-result.success { background: rgba(34, 197, 94, 0.08); border: 1px solid rgba(34, 197, 94, 0.2); color: #166534; } .ch-test-result.error { background: rgba(239, 68, 68, 0.08); border: 1px solid rgba(239, 68, 68, 0.2); color: #991b1b; } .ch-test-result .ch-test-title { font-weight: 600; margin-bottom: 3px; } .ch-test-result .ch-test-details { font-size: 11px; opacity: 0.85; } .ch-verify-result { margin-top: 8px; padding: 10px 12px; border-radius: 8px; font-size: 12px; line-height: 1.5; } .ch-verify-result.valid { background: rgba(34, 197, 94, 0.08); border: 1px solid rgba(34, 197, 94, 0.2); color: #166534; } .ch-verify-result.invalid { background: rgba(239, 68, 68, 0.08); border: 1px solid rgba(239, 68, 68, 0.2); color: #991b1b; } .ch-verify-result .ch-verify-title { font-weight: 600; margin-bottom: 3px; } .ch-verify-result .ch-verify-details { font-size: 11px; opacity: 0.85; } .ch-cookie-warning { background: linear-gradient(135deg, rgba(251, 191, 36, 0.1), rgba(245, 158, 11, 0.08)); border: 1px solid rgba(245, 158, 11, 0.2); border-radius: 10px; padding: 12px; margin-bottom: 10px; } .ch-warning-title { font-weight: 700; color: #92400e; margin-bottom: 6px; font-size: 13px; } .ch-warning-text { font-size: 11px; color: #a16207; line-height: 1.6; margin-bottom: 8px; } .ch-btn-tutorial { width: 100%; background: linear-gradient(135deg, #f59e0b, #d97706); color: white; border: none; padding: 8px 16px; border-radius: 8px; font-size: 12px; font-weight: 600; cursor: pointer; transition: all 0.15s; } .ch-btn-tutorial:hover { box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3); } .ch-manual-input-section { margin-top: 10px; } .ch-btn-manual { width: 100%; background: linear-gradient(135deg, #22c55e, #16a34a); color: white; border: none; padding: 9px 16px; border-radius: 8px; font-size: 12px; font-weight: 600; cursor: pointer; transition: all 0.15s; } .ch-btn-manual:hover { box-shadow: 0 2px 8px rgba(34, 197, 94, 0.3); } .ch-tutorial { padding: 0; border-top: 1px solid rgba(0, 0, 0, 0.06); } .ch-tutorial-header { background: rgba(0, 0, 0, 0.02); padding: 14px 18px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(0, 0, 0, 0.06); } .ch-tutorial-title { font-size: 14px; font-weight: 700; color: #1e293b; } .ch-close-tutorial { background: rgba(0, 0, 0, 0.06); border: none; color: #64748b; font-size: 20px; width: 28px; height: 28px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.15s; line-height: 1; } .ch-close-tutorial:hover { background: rgba(0, 0, 0, 0.1); transform: rotate(90deg); } .ch-tutorial-content { padding: 16px 18px; max-height: 350px; overflow-y: auto; } .ch-tutorial-step { display: flex; gap: 12px; margin-bottom: 14px; padding-bottom: 14px; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .ch-tutorial-step:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } .ch-step-number { flex-shrink: 0; width: 28px; height: 28px; background: linear-gradient(135deg, #6366f1, #8b5cf6); color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 12px; } .ch-step-text { flex: 1; font-size: 12px; line-height: 1.6; color: #475569; } .ch-step-text strong { display: block; margin-bottom: 3px; color: #1e293b; font-size: 13px; } .ch-step-text code { background: rgba(99, 102, 241, 0.08); padding: 2px 6px; border-radius: 4px; font-family: 'SF Mono', 'Cascadia Code', 'Courier New', monospace; font-size: 11px; color: #7c3aed; } .ch-toggle-btn { position: fixed; bottom: 24px; right: 24px; height: 44px; padding: 0 18px 0 14px; border-radius: 22px; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); color: white; border: none; font-size: 13px; font-weight: 700; cursor: pointer; box-shadow: 0 4px 20px rgba(99, 102, 241, 0.35), 0 0 0 1px rgba(255,255,255,0.1) inset; z-index: 999998; transition: transform 0.15s ease, box-shadow 0.2s ease, opacity 0.15s; display: flex; align-items: center; justify-content: center; gap: 6px; letter-spacing: 0.3px; user-select: none; -webkit-user-select: none; } .ch-toggle-btn:hover { transform: translateY(-2px) scale(1.02); box-shadow: 0 6px 24px rgba(99, 102, 241, 0.45), 0 0 0 1px rgba(255,255,255,0.15) inset; } .ch-toggle-btn:active { transform: translateY(0) scale(0.98); transition-duration: 0.05s; } .ch-toggle-btn.ch-toggle-active { background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%); box-shadow: 0 2px 12px rgba(99, 102, 241, 0.3); } .ch-toggle-btn::before { content: '🍪'; font-size: 18px; line-height: 1; } `; document.head.appendChild(style); document.body.appendChild(panel); // 创建切换按钮 const toggleBtn = document.createElement('button'); toggleBtn.className = 'ch-toggle-btn'; toggleBtn.id = 'ch-toggle-btn'; toggleBtn.textContent = 'Cookie助手'; toggleBtn.title = 'Cookie获取助手 - 点击打开'; document.body.appendChild(toggleBtn); return panel; } // 初始化 function init() { const panel = createPanel(); const currentPlatform = getCurrentPlatform(); // 事件处理 const closeBtn = document.getElementById('ch-close-btn'); const toggleBtn = document.getElementById('ch-toggle-btn'); const platformItems = document.querySelectorAll('.ch-platform-item:not(.disabled)'); const getCookieBtn = document.getElementById('ch-get-cookie-btn'); const copyBtn = document.getElementById('ch-copy-btn'); const refreshBtn = document.getElementById('ch-refresh-btn'); const testCookieBtn = document.getElementById('ch-test-cookie-btn'); const manualInputBtn = document.getElementById('ch-manual-input-btn'); const showTutorialBtn = document.getElementById('ch-show-tutorial-btn'); const closeTutorialBtn = document.getElementById('ch-close-tutorial-btn'); let selectedPlatform = null; // 检查并更新平台状态的函数 async function updatePlatformStatus(platformKey) { const platform = PLATFORMS[platformKey]; const statusEl = document.getElementById('ch-status'); const actionsEl = document.getElementById('ch-actions'); const resultEl = document.getElementById('ch-result'); resultEl.style.display = 'none'; // 检查是否在目标网站 const isOnTargetSite = window.location.hostname.includes(platform.domain); if (!isOnTargetSite) { // 不在目标网站,显示跳转按钮 statusEl.innerHTML = `📍 当前不在 ${platform.name} 网站`; statusEl.className = 'ch-status'; actionsEl.style.display = 'block'; refreshBtn.style.display = 'none'; getCookieBtn.textContent = `前往 ${platform.name}`; getCookieBtn.onclick = () => { if (typeof GM_openInTab !== 'undefined') { GM_openInTab(platform.url, { active: true }); } else { window.open(platform.url, '_blank'); } }; } else { // 在目标网站,检查登录状态 statusEl.textContent = '🔄 正在检测登录状态...'; statusEl.className = 'ch-status'; const isLoggedIn = await platform.checkLogin(); if (isLoggedIn) { statusEl.textContent = `✅ 已登录 ${platform.name}`; statusEl.className = 'ch-status success'; actionsEl.style.display = 'block'; refreshBtn.style.display = 'block'; getCookieBtn.textContent = '获取Cookie'; getCookieBtn.onclick = async () => { // 检查是否需要验证 if (requireVerification('getCookie', () => getCookieBtn.click())) return; const cookie = await platform.getCookie(); const cookieTextEl = document.getElementById('ch-cookie-text'); const cookieWarningEl = document.getElementById('ch-cookie-warning'); const warningDetail = document.getElementById('ch-warning-detail'); const statsEl = document.getElementById('ch-cookie-stats'); const statsText = document.getElementById('ch-stats-text'); if (cookie) { // 判断是否显示完整Cookie const canShowFull = isVerified() || !hasUsedFreeTrial(); cookieTextEl.value = canShowFull ? cookie : maskCookie(cookie); // 存储完整cookie供验证后使用 cookieTextEl.dataset.fullCookie = cookie; resultEl.style.display = 'block'; const cookieCount = cookie.split(';').filter(s => s.trim()).length; const checkResult = checkCookieComplete(cookie); statsEl.style.display = 'block'; statsText.innerHTML = `📊 共获取 ${cookieCount} 个Cookie | ${checkResult.summary}`; if (!checkResult.complete) { cookieWarningEl.style.display = 'block'; if (checkResult.missing.length > 0) { warningDetail.innerHTML = `缺少重要字段: ${checkResult.missing.join(', ')}

` + (checkResult.usable ? '当前Cookie基本可用,但部分功能可能受限。
如需完整Cookie,请使用下方"手动输入"功能:' : '由于浏览器安全限制,脚本无法获取HttpOnly Cookie。
请使用下方的"手动输入"功能获取完整Cookie:'); } } else { cookieWarningEl.style.display = 'none'; } // 如果是免费次数,记录使用 if (!hasUsedFreeTrial()) { recordUse(); } if (typeof GM_notification !== 'undefined') { GM_notification({ text: checkResult.complete ? 'Cookie获取成功!' : (checkResult.usable ? 'Cookie基本可用,部分字段缺失' : 'Cookie不完整,请使用手动输入'), timeout: 2000 }); } } else { alert('获取Cookie失败,请确保已登录'); } }; } else { statusEl.textContent = `❌ 暂未登录 ${platform.name},请先登录`; statusEl.className = 'ch-status error'; actionsEl.style.display = 'block'; refreshBtn.style.display = 'block'; getCookieBtn.style.display = 'none'; } } } // 切换面板显示(即时响应,异步刷新避免卡顿) toggleBtn.addEventListener('click', () => { const isHidden = panel.style.display === 'none' || !panel.style.display; if (isHidden) { panel.style.display = 'flex'; // 强制回流后再加动画class,确保transition生效 panel.offsetHeight; panel.classList.add('ch-panel-open'); toggleBtn.classList.add('ch-toggle-active'); // 异步刷新状态,不阻塞面板打开动画 if (selectedPlatform) { setTimeout(() => updatePlatformStatus(selectedPlatform), 100); } } else { panel.classList.remove('ch-panel-open'); toggleBtn.classList.remove('ch-toggle-active'); setTimeout(() => { panel.style.display = 'none'; }, 250); } }); closeBtn.addEventListener('click', () => { panel.classList.remove('ch-panel-open'); toggleBtn.classList.remove('ch-toggle-active'); setTimeout(() => { panel.style.display = 'none'; }, 250); }); // 选择平台 platformItems.forEach(item => { item.addEventListener('click', (e) => { // 如果点击的是测试按钮,不触发平台选择 if (e.target.classList.contains('ch-platform-test-btn')) { return; } const platformKey = item.dataset.platform; // 更新选中状态 platformItems.forEach(i => i.classList.remove('active')); item.classList.add('active'); selectedPlatform = platformKey; // 更新平台状态 updatePlatformStatus(platformKey); }); }); // 平台测试按钮 document.querySelectorAll('.ch-platform-test-btn').forEach(btn => { btn.addEventListener('click', async (e) => { e.stopPropagation(); // 阻止事件冒泡 const platformKey = btn.dataset.platform; const platform = PLATFORMS[platformKey]; // 检查是否在目标网站 const isOnTargetSite = window.location.hostname.includes(platform.domain); if (!isOnTargetSite) { const goToSite = confirm(`当前不在${platform.name}网站。\n\n是否前往${platform.name}进行测试?`); if (goToSite) { if (typeof GM_openInTab !== 'undefined') { GM_openInTab(platform.url, { active: true }); } else { window.open(platform.url, '_blank'); } } return; } // 在目标网站上,弹出输入框 const cookieInput = prompt(`请输入要测试的${platform.name} Cookie:\n\n提示:可以从F12开发者工具的网络请求中复制完整Cookie`); if (!cookieInput || !cookieInput.trim()) { return; } // 执行登录测试 const verifyResultEl = document.getElementById('ch-verify-result'); const resultEl = document.getElementById('ch-result'); resultEl.style.display = 'block'; verifyResultEl.style.display = 'block'; verifyResultEl.className = 'ch-verify-result'; verifyResultEl.innerHTML = `
🔄 正在测试Cookie...
请稍候
`; try { const result = await testLoginWithCookie(cookieInput.trim()); verifyResultEl.className = `ch-verify-result ${result.valid ? 'valid' : 'invalid'}`; verifyResultEl.innerHTML = `
${result.valid ? '✅ ' : '❌ '}${result.message}
${result.details}
`; if (typeof GM_notification !== 'undefined') { GM_notification({ text: result.message, timeout: 3000 }); } // 如果登录成功,3秒后刷新页面 if (result.needRefresh) { setTimeout(() => { window.location.reload(); }, 3000); } } catch (error) { verifyResultEl.className = 'ch-verify-result invalid'; verifyResultEl.innerHTML = `
❌ 测试失败
${error.message}
`; } }); }); // 刷新按钮事件 refreshBtn.addEventListener('click', () => { if (selectedPlatform) { updatePlatformStatus(selectedPlatform); if (typeof GM_notification !== 'undefined') { GM_notification({ text: '状态已刷新', timeout: 1000 }); } } }); // 获取Cookie getCookieBtn.addEventListener('click', () => { // 这个事件监听器现在只是占位,实际逻辑在平台选择时动态绑定 }); // 复制Cookie copyBtn.addEventListener('click', () => { // 复制需要验证(免费次数用完后) if (requireVerification('copy', () => copyBtn.click())) return; const cookieTextEl = document.getElementById('ch-cookie-text'); const cookie = cookieTextEl.dataset.fullCookie || cookieTextEl.value; if (typeof GM_setClipboard !== 'undefined') { GM_setClipboard(cookie); copyBtn.textContent = '✅ 已复制'; setTimeout(() => { copyBtn.textContent = '📋 复制'; }, 2000); } else { cookieTextEl.value = cookie; // 确保显示完整内容用于选择 cookieTextEl.select(); document.execCommand('copy'); copyBtn.textContent = '✅ 已复制'; setTimeout(() => { copyBtn.textContent = '📋 复制'; }, 2000); } }); // 测试Cookie(退出重登) testCookieBtn.addEventListener('click', async () => { if (requireVerification('test', () => testCookieBtn.click())) return; const cookieTextEl = document.getElementById('ch-cookie-text'); const cookie = cookieTextEl.dataset.fullCookie || cookieTextEl.value; if (!cookie || !cookie.trim()) { alert('请先获取或输入Cookie'); return; } if (!confirm('⚠️ 此操作将清除当前登录状态,使用获取的Cookie重新登录。\n\n确定要继续吗?')) { return; } testCookieBtn.disabled = true; testCookieBtn.textContent = '🔄 测试中...'; try { // 1. 清除当前所有Cookie if (typeof GM_cookie !== 'undefined') { const currentCookies = await new Promise((resolve) => { GM_cookie.list({}, (cookies) => { resolve(cookies || []); }); }); for (const c of currentCookies) { await new Promise((resolve) => { GM_cookie.delete({ name: c.name, url: window.location.href }, () => resolve()); }); } } // 2. 设置新Cookie const result = await testLoginWithCookie(cookie); // 3. 刷新页面验证 if (result.valid || result.needRefresh) { if (typeof GM_notification !== 'undefined') { GM_notification({ text: '正在刷新页面验证登录...', timeout: 2000 }); } setTimeout(() => { window.location.reload(); }, 2000); } else { alert(`测试失败:${result.message}\n${result.details}`); testCookieBtn.disabled = false; testCookieBtn.textContent = '🧪 测试Cookie(退出重登)'; } } catch (error) { alert(`测试失败:${error.message}`); testCookieBtn.disabled = false; testCookieBtn.textContent = '🧪 测试Cookie(退出重登)'; } }); // 手动输入Cookie manualInputBtn.addEventListener('click', () => { if (requireVerification('manual', () => manualInputBtn.click())) return; const cookieTextEl = document.getElementById('ch-cookie-text'); const cookieWarningEl = document.getElementById('ch-cookie-warning'); const statsEl = document.getElementById('ch-cookie-stats'); const statsText = document.getElementById('ch-stats-text'); const userInput = prompt('请粘贴从F12开发者工具复制的完整Cookie:\n\n提示:在开发者工具的"网络"标签中,找到任意请求,复制"请求标头"中的Cookie值'); if (userInput && userInput.trim()) { cookieTextEl.value = userInput.trim(); cookieTextEl.dataset.fullCookie = userInput.trim(); const cookieCount = userInput.trim().split(';').filter(s => s.trim()).length; const checkResult = checkCookieComplete(userInput.trim()); statsEl.style.display = 'block'; statsText.innerHTML = `📊 共 ${cookieCount} 个Cookie | ${checkResult.summary}`; if (checkResult.complete) { cookieWarningEl.style.display = 'none'; if (typeof GM_notification !== 'undefined') { GM_notification({ text: '✅ 完整Cookie已输入!', timeout: 2000 }); } } else { if (typeof GM_notification !== 'undefined') { GM_notification({ text: checkResult.usable ? '⚠️ Cookie基本可用,部分字段缺失' : '⚠️ Cookie可能仍不完整', timeout: 2000 }); } } } }); // 验证Cookie有效性 const verifyCookieBtn = document.getElementById('ch-verify-cookie-btn'); verifyCookieBtn.addEventListener('click', async () => { if (requireVerification('verify', () => verifyCookieBtn.click())) return; const cookieTextEl = document.getElementById('ch-cookie-text'); const cookie = cookieTextEl.dataset.fullCookie || cookieTextEl.value; if (!cookie || !cookie.trim()) { alert('请先获取或输入Cookie'); return; } verifyCookieBtn.disabled = true; verifyCookieBtn.textContent = '🔄 验证中...'; try { const platform = PLATFORMS[selectedPlatform]; let result; if (platform && platform.verifyCookie) { result = await platform.verifyCookie(); } else { result = verifyByPageContent(); } // 显示验证结果 let verifyResultEl = document.getElementById('ch-verify-result'); if (!verifyResultEl) { verifyResultEl = document.createElement('div'); verifyResultEl.id = 'ch-verify-result'; verifyCookieBtn.parentNode.appendChild(verifyResultEl); } verifyResultEl.style.display = 'block'; verifyResultEl.className = `ch-verify-result ${result.valid ? 'valid' : 'invalid'}`; verifyResultEl.innerHTML = `
${result.valid ? '✅ ' : '❌ '}${result.message}
${result.details}
`; if (typeof GM_notification !== 'undefined') { GM_notification({ text: result.message, timeout: 3000 }); } } catch (error) { alert(`验证失败:${error.message}`); } finally { verifyCookieBtn.disabled = false; verifyCookieBtn.textContent = '🔍 验证Cookie有效性'; } }); // 显示教程 showTutorialBtn.addEventListener('click', () => { const tutorialEl = document.getElementById('ch-tutorial'); tutorialEl.style.display = 'block'; }); // 关闭教程 closeTutorialBtn.addEventListener('click', () => { const tutorialEl = document.getElementById('ch-tutorial'); tutorialEl.style.display = 'none'; }); // 如果在支持的平台上,自动选中 if (currentPlatform && !PLATFORMS[currentPlatform].disabled) { const platformItem = document.querySelector(`[data-platform="${currentPlatform}"]`); if (platformItem) { platformItem.click(); } } } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();