Skip to content

🐛 修复 360 X 从网页新开标签安装脚本时安装页加载失败 #1816 - #1818

Open
CodFrm wants to merge 1 commit into
mainfrom
fix/360x-install-context
Open

CodFrm wants to merge 1 commit into
mainfrom
fix/360x-install-context

Conversation

@CodFrm

@CodFrm CodFrm commented Nov 2, 2026

Copy link
Copy Markdown
Member

Checklist / 检查清单

  • Fixes mentioned issues / 修复已提及的问题
  • Code reviewed by human / 代码通过人工检查
  • Changes tested / 已完成测试

背景

360 X 浏览器里,从网页上的「安装脚本」按钮安装会失败,安装页报 Invalid context type provided.(#1816)。

实机复现后确认,触发条件是网页以 noopener 新开的标签被 DNR 重定向到安装页。这时页面拿到的扩展 API 不完整:chrome.tabs、chrome.permissions、chrome.runtime.getContexts 都是 undefined,安装页准备脚本时一读 chrome.storage.local 就报错。同一个链接不带 noopener 打开则一切正常,和开发者模式无关。360 X 为什么这样给页面分类还不清楚。在本页刷新、或者让原标签重新导航都恢复不了,只有由 SW 用 tabs.create 新开的安装页才正常。

本次改动

安装页入口在渲染前做一次检测:如果 chrome.tabs 不存在,且 URL 带 ?url=(只有 DNR 拦截才会产生这种入口),就 location.replace 到文档站现成的安装中间页 docs.scriptcat.org/docs/script_installation/#url=<脚本地址>。

SW 现有的 webNavigation.onBeforeNavigate 监听会接住这次导航,备好脚本后通过 openInCurrentTab(tabs.create)新开 ?uuid= 安装页,新标签拿到的是完整上下文。这条中间页链路是现成的,访问不了文档站时也能触发(#705)。

实现考虑

  • 为什么做浏览器兼容分支,而不是把特权调用全部挪进 SW。 页面直接读 Repo 是现有的正常写法(脚本编辑器、导入页、favicon 都这么做),所以不存在需要修正的架构问题。而且 BackgroundPrompt 里的 chrome.permissions.request 必须在页面里、带用户手势调用,挪不走。为一个浏览器的问题重构,改不全,以后也容易再坏。
  • 用特性检测而不是 UA 判断。 正常扩展页里 chrome.tabs 一定存在,所以其他浏览器不会进这个分支。
  • 不会循环。 只有 ?url= 入口会跳转,SW 新建的是 ?uuid= 入口,不会再落回这里。url= 之后的整段原样转交,和安装页读取 ?url= 的方式一致,脚本地址自带的查询串不会被截断。
  • 代码注释里标明了这是 [BUG] 360 X 浏览器 安装脚本失败 #1816 的兼容处理,并说明根因尚未确认。

已知限制

  • 走兼容路径时,原标签会停在文档站的中间页(新安装页成为活动标签,SW 不会对原标签执行 goBack)。这和现在从文档站中间页安装的表现一致。
  • 只在 360 X 23.1.1298.64(Chromium 132)上实机验证过。其他存在同类问题的国产 Chromium 浏览器,理论上会走同一分支,但没有测过。

验证

  • pnpm exec vitest run --no-coverage src/pages/install/context_fallback.test.ts:3 passed。先在模块不存在时确认失败,再写实现。
  • pnpm run typecheck,以及改动文件的 eslint 和 prettier 检查:通过。提交钩子里的 typecheck、prettier 检查也通过。
  • pnpm exec vitest run --no-coverage src/pages/install:每次有 3 个用例失败,但每次失败的不是同一批(一次是 compat_docs,另一次是 BackgroundPrompt 和 PermissionCard)。去掉本次改动在 main 上跑,同样失败 3 个;三个文件单独跑全部通过(3/3、5/5、31/31)。本次改动的文件没有被这些测试引用,判断是既有的并行不稳定用例。
  • 360 X 实机(Windows 11,360 X 23.1.1298.64,全新临时 profile、开发者模式,解压加载 pnpm run build 产物,通过 CDP 发送真实鼠标事件驱动):
    • 修复前(origin/main 构建):点击 scriptcat.org 详情页的「安装脚本」,install.html?url=... 里 chrome.tabs、chrome.permissions 都是 undefined,页面报 Invalid context type provided.,复现了问题。
    • 修复后:同一操作,原标签转到文档中间页,新标签打开 install.html?uuid=...,chrome.tabs、chrome.permissions 都是 object,安装内容正常显示。点击「安装」后,从 SW 读取 chrome.storage.local,能看到该脚本的记录(status 1),安装页随后自动关闭。
    • 对照:在 example.com 上注入同一个 .user.js 链接测试,带 rel=noopener 时自动恢复,不带时停在原 ?url= 安装页,没有跳转。
  • 没有在桌面版 Chrome 上单独跑。正常上下文不跳转,由单测和上面 360 X 的不带 noopener 对照覆盖。
  • 范围:git diff 79f2a99f...ea6675f8 只涉及 src/pages/install/{context_fallback.ts,context_fallback.test.ts,main.tsx}。

关联

fix #1816

Screenshots / 截图

以下截图均为 360 X 实机上用 CDP 截取的页面视口(不含地址栏),URL 和 API 状态见上方「验证」。

修复前:从网页按钮进入的安装页

360x-before-install-page-error

修复后:自动新开的 ?uuid= 安装页正常加载

360x-after-install-page-recovered

修复后:点击「安装」后的成功状态(随后页面自动关闭)

360x-after-installed

修复后:原标签停在文档站安装中间页

360x-after-original-tab-docs-page

@cyfung1031

Copy link
Copy Markdown
Collaborator

看起来应该行吧
AI测过没事就可以。有问题再修

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] 360 X 浏览器 安装脚本失败

2 participants