commit 83ca948ea648413010e786aef3acd86470fbe0ff Author: chickliu Date: Tue Nov 11 11:29:16 2025 +0800 上传文件至 js diff --git a/js/ksjsb_ck_x.js b/js/ksjsb_ck_x.js new file mode 100644 index 0000000..879b973 --- /dev/null +++ b/js/ksjsb_ck_x.js @@ -0,0 +1,111 @@ +/* + * @name: 快手 Salt 获取 + * @description: 抓取快手登录响应以获取 Salt + * @author: + * @version: 1.0.1 + * + * 脚本使用方法: + * 1. 将此脚本保存到 Quantumult X 的脚本目录中 (例如 iCloud/QuantumultX/Scripts/)。 + * 2. 在 Quantumult X 配置文件 ([rewrite_local] 部分) 中添加以下行: + * https:\/\/txjp\.gifshow\.com\/rest\/nebula\/user\/login\/mobileVerifyCode url script-response-body https://raw.githubusercontent.com/your/repo/ks_salt_notify.js + * (请将上面的 URL 替换为您自己的脚本路径) + * 3. 在 Quantumult X 配置文件 ([mitm] 部分) 中添加主机名: + * hostname = txjp.gifshow.com + * 4. 打开快手 App,触发登录或刷新登录状态 (访问上述 URL)。 + * 5. 成功后,脚本会自动弹出通知显示获取到的 "kuaishou.api_client_salt" 值。 + */ + +// ############################### +// ###### 脚本主逻辑 ###### +// ############################### + +const $ = new Env(); +const targetUrl = 'https://txjp.gifshow.com/rest/nebula/user/login/mobileVerifyCode'; + +(async () => { + // 仅当 URL 匹配时执行 + if ($request.url.includes(targetUrl)) { + $.log('ℹ️ 捕获到目标URL: ' + $request.url); + + try { + // 1. 解析响应体 + const body = JSON.parse($response.body); + + // 2. 从响应体中获取 kuaishou.api_client_salt (根据你的要求) + // 使用方括号语法来访问带点的key + const salt = body?.['kuaishou.api_client_salt']; + + if (salt) { + // 3. 获取成功,发出通知 + $.log(`✅ 成功获取 kuaishou.api_client_salt: ${salt}`); + // Quantumult X 的通知点击后,body 内容会自动复制到剪贴板 + $.notify("快手Salt获取成功", "点击通知可复制", salt); + } else { + // 4. 获取失败,发出通知 + $.log('❌ 未在响应体中找到 kuaishou.api_client_salt'); + $.notify("快手Salt获取失败", "响应体中未找到", "请检查响应数据或脚本。"); + } + } catch (e) { + $.logErr(e); + $.notify("快手Salt脚本出错", "解析响应体失败", e.message); + } + + } else { + $.log('⚠️ 当前URL不匹配,脚本不执行。'); + } +})().catch((e) => { + $.logErr(e); + $.notify("快手Salt脚本异常", "发生未知错误", e.message); +}).finally(() => { + $.done(); +}); + + +// 兼容多环境的 Env 类 +function Env() { + const isQuanX = typeof $task !== 'undefined'; + const isSurge = typeof $httpClient !== 'undefined' && !isQuanX; + const isLoon = typeof $loon !== 'undefined'; + const isNode = typeof require === 'function'; + + const http = { + get: (options) => { + return new Promise((resolve, reject) => { + if (isQuanX) $task.fetch(options).then(resp => resolve(resp), err => reject(err)); + else if (isSurge || isLoon) $httpClient.get(options, (err, resp, body) => err ? reject(err) : resolve({ body, status: resp.statusCode, headers: resp.headers })); + else if (isNode) { + const request = require('request'); + request(options, (err, resp, body) => err ? reject(err) : resolve({ body, status: resp.statusCode, headers: resp.headers })); + } + }); + }, + post: (options) => { + return new Promise((resolve, reject) => { + if (isQuanX) $task.fetch(options).then(resp => resolve(resp), err => reject(err)); + else if (isSurge || isLoon) $httpClient.post(options, (err, resp, body) => err ? reject(err) : resolve({ body, status: resp.statusCode, headers: resp.headers })); + else if (isNode) { + const request = require('request'); + request.post(options, (err, resp, body) => err ? reject(err) : resolve({ body, status: resp.statusCode, headers: resp.headers })); + } + }); + }, + put: (options) => { + return new Promise((resolve, reject) => { + if (isQuanX) $task.fetch({ ...options, method: 'PUT' }).then(resp => resolve(resp), err => reject(err)); + // ... 其他环境的实现 + }); + } + }; + + const notify = (title, subtitle = '', body = '') => { + if (isQuanX) $notify(title, subtitle, body); + else console.log(`${title}\n${subtitle}\n${body}`); + }; + + const log = (msg) => console.log(msg); + const logErr = (e) => console.log(e); + + const done = (value = {}) => isQuanX ? $done(value) : null; + + return { http, notify, log, logErr, done }; +} \ No newline at end of file