// ==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 = `
⚠️ 免责声明(请先阅读)
${DISCLAIMER}
请选择一个平台
⚠️ Cookie不完整
由于浏览器安全限制,脚本无法获取HttpOnly Cookie(如web_session、id_token等)。
请使用下方的"手动输入"功能获取完整Cookie:
点击后将清除当前登录,使用此Cookie重新登录以验证有效性
1
打开开发者工具
按 F12 或右键点击页面选择"检查"
2
切换到"网络"标签
找到顶部的"Network"或"网络"标签并点击
4
找到homefeed请求
在左侧列表中搜索"homefeed"或"feed",点击任意一个请求
5
复制Cookie
在右侧找到"请求标头"→"Cookie",点击Cookie值,全选并复制
6
粘贴到脚本
点击下方"手动输入完整Cookie"按钮,粘贴刚才复制的内容
`;
// 添加样式
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();
}
})();