Files
TPSchedule/docs/school-webview-missing-head-analysis-2026-10-15.md
T

4.4 KiB
Raw Blame History

教务页面缺少公共头部:证据与修复设计

2026-10-15,TPSchedule 0.7.2+20。本文不包含学生原始HTML、请求凭证或原始日志。

已确认的证据

用户更正后的日志导出于北京时间15:41:07。15:40:47后,学校认证返回本科系统,读取证据authenticated=true;控制台先后记录reference_error和jquery_missing。原生页面状态为脚本标签2、样式表0、样式链接0,jQuery、Beangle和Require均不存在。这是登录后基础依赖未进入页面的证据,不能用调整课表解析器解决。

15:31–15:32的空白尝试属于用户后来确认未连接校园网时的记录,应与联网后组件缺失区分。身份认证图片404和此前主文档连接错误不能直接当作15:40教务页面的根因。

此前用户提供的Chrome导出本科HTML,其head包含多组jQuery、Beangle、Require及CSS依赖。仓库未复制原始附件。

官方源码交叉核对

  1. Beangle旧Java框架的head.ftl以请求头和同名参数是否存在,决定是否输出公共head。判断并非仅比较XMLHttpRequest值;把头改为空字符串并不能据此保证输出head。该规则可以产生正文和少数内联脚本仍在、公共脚本和样式缺失的现象。
  2. Chromium的Android WebView网络实现会在请求尚未显式设置X-Requested-With时添加宿主包名,且注明该自动值对shouldInterceptRequest不可见。因此仅看拦截回调中的请求头也不足以证明线上没有该头。
  3. AndroidX WebSettingsCompat文档说明setRequestedWithHeaderOriginAllowList自1.15.0起失效;当前固定WebView插件依赖的正是AndroidX WebKit1.15.0。不能把该接口当作有效修复,也不应为此偷偷降级插件依赖。

三者与日志高度吻合,但尚未直接捕获用户手机的线上请求头,也没有获得受影响在线页面的原始响应;该原因仍应标为高概率推断。用户暂不方便USB联调,后续继续文件与可验证的兼容处理。

有界修复设计(用户已确认,2026-10-15)

目标保持原学校网页登录、验证码、手动选择本科课表及APP读取流程。仅针对已认证而缺少公共依赖的学校页面增加完整页恢复,沿用系统WebView。

  • 学生仍在学校网页输入账号密码和验证码,应用不接管输入。
  • 对受限制的学校HTTPS只读页面,用同一登录会话请求原地址的完整HTML;该请求不携带触发片段输出的X-Requested-With标记。Cookie只用于原学校域名,不进入日志、反馈或其他服务器。
  • 读取到完整页面并验证来源、状态、类型及大小后,再交给现有WebView显示。异常、跳转到认证页、页面已变更、退出、取消或超限时不替换当前页面,不导入或清空旧课表。
  • 不接管验证码、选课、提交表单等POST操作;不放宽HTTPS证书校验,不修改学校安全策略;完整页恢复次数有限,避免循环刷新。
  • 先以框架同类片段/完整页规则、会话隔离、取消和恶意跳转做回归,再做Android原生验证。真实学校账号复测仍是最终确认,测试通过不能代替该确认。

用户已明确确认同会话完整页读取和现有WebView显示的方案。0.7.3先接入有明确日志证据的本科系统,研究生流程保持原有实现。

实现边界

Android原生读取只允许准确学校域名下有限的只读路由、HTTPS默认端口及GET;拒绝凭证或业务操作查询字段、跳转、非HTML、超限响应。连接使用默认TLS校验,读取超时和解压前后均有上限。Cookie由原生CookieManager取出,仅发往原学校;返回Cookie限制为同域和系统路径。不写磁盘或日志。

完整HTML经Flutter确认公共脚本、CSS及已登录结构后,原生使用20秒有效的单次令牌恢复页面。页面URL、WebView实例、当前登录Cookie和Flutter文档代次均需匹配;恢复地址和来源保留原学校HTTPS。一个文档最多尝试一次、一次打开最多四次;暂存全局最多四项,后台读取两个工作线程和两个排队任务。失败保留当前页面,导入仍沿用原有确认与保存流程。