Appearance
登录、Cookie 与人机验证
登录配置
Readori 书源可以使用 loginUrl、loginUi 和 loginCheckJs。登录 UI 支持字段、按钮、 线路/设置动作和脚本执行;真实网页登录由 WKWebView 承载。loginUi 以原始 JSON 字符串 形式保存在书源里,具体表单渲染由登录界面负责解析,不在规则求值链路里;书源作者一般直接 从来源站点或已有书源里复制这段 JSON,不需要从零手写。
loginCheckJs 不是简单的布尔判断
容易搞混的一点:loginCheckJs 不是“返回 true/false 表示已登录”的检查函数,而是一段 响应拦截器——它在搜索、发现、详情、目录、正文等每一次请求返回后都会执行一次, result 绑定的是当前这次响应(可以调用 result.body() 之类的方法取正文),脚本必须 返回一个同样形状的响应对象(通常就是处理后的 result 本身),而不是一个真假值:
js
// 最简单的形式:不修改响应,只是让登录态在每次请求后都被复核一次
resultjs
// 常见形式:发现响应体带有登录跳转特征时,记一次日志/更新书源级变量,
// 方便后续排查,但依然把原始响应原样传回去——JS 侧拿到的 result 是只读代理对象,
// 没有能重写响应体的方法,loginCheckJs 更适合做"检测 + 记录/提示",
// 不是用来篡改正文
if (result.body().indexOf('请先登录') >= 0) {
source.put('lastLoginCheckFailedAt', String(Date.now()));
java.log('loginCheckJs: 检测到未登录状态,' + result.url());
}
result如果这一步返回的不是一个可识别的响应对象(比如手滑写成了 true),对应请求会直接失败 并在诊断里报 loginCheckJs did not return StrResponse,而不是被当成“未登录”静默跳过。
Cookie 生命周期
Cookie 按序列化 bookSourceUrl 隔离。请求时合并来源 headers、URL options 和 CookieJar。 规则显式提供的 Cookie 优先,避免旧 CookieJar 值覆盖脚本刚生成的 token。
交互式浏览器关闭时会把 WKWebView Cookie 写回来源 CookieJar,供随后的搜索、目录和正文 请求使用。规则 JS 里可以用 cookie.getCookie(url)/cookie.setCookie(url, str) 直接读写, 详见 JS 执行上下文。
人机验证
验证请求使用 request ID 管理:相同挑战可以合并,不同挑战按队列展示,超时和关闭只取消 对应等待者。批量书源验证不会同时弹出大量交互窗口;需要人工操作的来源应标为“需要 交互”,而不是伪造通过。
常见故障
- 登录成功但搜索未登录:检查 Cookie 域、来源身份和显式 Cookie 覆盖;
- 验证窗口重复:检查是否由同一请求多次注册、旧 callback 是否仍有效;
- 关闭无响应:需要确认精确 waiter 已取消,且没有第二个队列项立即覆盖;
- 聚合设置空白:检查
loginUi非严格 JSON 解析以及按钮动作是否保存当前输入字段。
