fix: 修复缺少站点访问权限时跨域请求异常的问题#1477
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
该 PR 旨在修复当浏览器未授予扩展对目标站点的“站点访问权限”时,脚本发起 GM.xmlHttpRequest / GM_xmlhttpRequest 跨域请求可能出现非预期异常的问题。整体思路是在原有 @connect / CORS 确认链路之外,增加对扩展“站点访问权限(Site access)”的检测与引导授权,从而避免在权限被浏览器侧拦截时产生不可控错误。
Changes:
- 在 Service Worker 侧为 XHR 跨域请求增加
chrome.permissions.contains检测,并在缺少站点访问权限时返回新的确认类型extension-site-access - 在确认页面中增加
chrome.permissions.request({ origins })的用户手势授权流程,并为extension-site-access场景简化按钮 UI - 为多语言资源补充“需要站点访问权限”的标题/描述/内容文案
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pages/confirm/App.tsx | 确认页新增站点访问权限请求逻辑,并对 extension-site-access 场景简化按钮 |
| src/app/service/service_worker/permission_verify.ts | 扩展 ConfirmParam,增加 extensionSiteAccessOrigins 字段用于确认页触发权限申请 |
| src/app/service/service_worker/gm_api/gm_api.ts | XHR 权限确认前新增站点访问权限检测,必要时返回 extension-site-access 确认 |
| src/locales/zh-TW/translation.json | 新增站点访问权限相关文案(繁中) |
| src/locales/zh-CN/translation.json | 新增站点访问权限相关文案(简中) |
| src/locales/vi-VN/translation.json | 新增站点访问权限相关文案(越南语) |
| src/locales/ru-RU/translation.json | 新增站点访问权限相关文案(俄语) |
| src/locales/ja-JP/translation.json | 新增站点访问权限相关文案(日语) |
| src/locales/en-US/translation.json | 新增站点访问权限相关文案(英语) |
| src/locales/de-DE/translation.json | 新增站点访问权限相关文案(德语) |
Comment on lines
+48
to
+62
| if (allow && confirm?.extensionSiteAccessOrigins?.length) { | ||
| const granted = await chrome.permissions.request({ | ||
| origins: confirm.extensionSiteAccessOrigins, | ||
| }); | ||
| if (!granted) { | ||
| await permissionClient | ||
| .confirm(uuid, { | ||
| allow: false, | ||
| type, | ||
| }) | ||
| .catch(() => {}); | ||
| window.close(); | ||
| return; | ||
| } | ||
| } |
Comment on lines
+810
to
+817
| const originPattern = `${url.origin}/*`; | ||
| let hasOriginPermission = false; | ||
| try { | ||
| hasOriginPermission = await chrome.permissions.contains({ origins: [originPattern] }); | ||
| } catch (e) { | ||
| console.warn(e); | ||
| } | ||
| const extensionSiteAccessOrigins = hasOriginPermission ? undefined : [originPattern]; |
Collaborator
Author
Collaborator
Author
|
@CodFrm 你知不知道有什么情况才会有由「所有网络」变成「特定网站」的情况吗? 脚本安装页弹出也是用 DNR,如果是「特定网站」的情况下就会失效... |
Member
一般是用户自己设定吧,其它情况我也不清楚了 |
CodFrm
added a commit
to cyfung1031/scriptcat
that referenced
this pull request
Jun 11, 2026
- gm-api.spec.ts: scriptscat#1477 迁移到本地 mock server 时漏改 unwrap 测试,仍引用已删除的 TARGET_URL 导致 ReferenceError。改用 cspOrigin,并把 unwrap_e2e_test token 接入 patchTargetMatchCode - concurrency-control.test.ts: 操作全局计时器/console 的 3 个用例从 it.concurrent 改回顺序 it,避免并发互相干扰偶现失败
CodFrm
added a commit
that referenced
this pull request
Jun 11, 2026
* x
* 处理并行fetch问题
* 修复 src/app/service/service_worker/runtime.ts
* 本地资源代码更新逻辑修正
* Update script.ts
* fix
* getResourceByType -> getResourceByTypes
* 加入注意
* getScriptResources -> getScriptResourceValue
* 代码调整
* `mdValue.startsWith("file:///")` -> `resourcePath.startsWith("file:///")`
* 代码调整
* 代码调整
* 代码调整
* `loadByUrl` -> `createResourceByUrlFetch`
* 简化 updateResource signature
* 简化 createResourceByUrlFetch
* lint
* `updateResourceByType` -> `updateResourceByTypes`
* 加注釋
* 代码优化 - 资源更新条件修改
* 注釋
* lint
* 调整代码 - updateResource & createResourceByUrlFetch
* 统一 try catch 在 updateResource 里进行
* 修正 Semaphore 相关代码
* 把并行控制的代码移动至 concurrency-control.ts
* Update src/app/service/service_worker/resource.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/app/service/service_worker/utils.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* ♻️ 优化资源加载代码:提取魔法数字、清理疑问注释、添加并发控制单元测试
- 提取魔法数字为命名常量(MAX_CONCURRENT_FETCHES, FETCH_DELAY, FETCH_SEMAPHORE_TIMEOUT, RESOURCE_CACHE_TTL)
- 清理疑问注释,改为明确的设计决策说明
- 为 Semaphore 和 withTimeoutNotify 添加单元测试
* 改回注释
* 按AI指示语意更新
* 根据AI意见修正
* fix
* 修正 Semaphore
* fix unit test
* unit test fix
* Commits 整合
* ✅ add failing tests for resource concurrency regressions
* 🐛 修复资源更新缓存与并发控制
* 🐛 修复资源 TTL 命中时未登记 link 导致共享资源被误删
updateResourceByTypes 在 24 小时 TTL 命中时直接 return,不会把当前脚本 uuid 写入 resource.link。多个脚本复用同一 URL 时,删除其中一个脚本会把仍被其它脚本使用的资源一并删除。
TTL 命中时也补登记 link(只更新 link 字段,避开 getResourceModel 对 SRI 校验失败时改写 content 的副作用)。
* ✅ 修复 unwrap e2e 测试与并发测试的全局状态污染
- gm-api.spec.ts: #1477 迁移到本地 mock server 时漏改 unwrap 测试,仍引用已删除的 TARGET_URL 导致 ReferenceError。改用 cspOrigin,并把 unwrap_e2e_test token 接入 patchTargetMatchCode
- concurrency-control.test.ts: 操作全局计时器/console 的 3 个用例从 it.concurrent 改回顺序 it,避免并发互相干扰偶现失败
---------
Co-authored-by: 王一之 <yz@ggnb.top>
Co-authored-by: wangyizhi <i@xloli.top>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CodFrm
added a commit
that referenced
this pull request
Jun 12, 2026
为 v1.4.0-beta.3 → beta.4 的核心改动补充 Playwright E2E(复用现有两阶段 userScripts fixture,并新增本地 mock server + host-resolver 域名映射,全程不依赖外网): - resource-update: @require/@resource 注入与读取、24h TTL 同 URL 去重、 拉取失败优雅降级、多 require 并发全部加载 (#1193) - gm-xhr-site-access: 跨域 @connect 放行、x-sc-request-marker 经 DNR 剥离、 非 @connect 域名拒绝 (#1477, mv3_utils) - background-script: @background 脚本经 Chrome offscreen 执行并具备 DOM 环境 (#1457) - user-config-yaml: 含 __proto__ 的恶意 @userconfig 被拒、原型链未污染 (#1494) - backup-zip: 备份导出/导入 zip 往返(JSZipp generateAsync/loadAsync)(#1479) - server-fixtures: 共享 fixture + mock server
CodFrm
added a commit
that referenced
this pull request
Jun 12, 2026
为 v1.4.0-beta.3 → beta.4 的核心改动补充 Playwright E2E(复用现有两阶段 userScripts fixture,并新增本地 mock server + host-resolver 域名映射,全程不依赖外网): - resource-update: @require/@resource 注入与读取、24h TTL 同 URL 去重、拉取失败优雅降级、多 require 并发全部加载 (#1193) - gm-xhr-site-access: 跨域 @connect 放行、x-sc-request-marker 经 DNR 剥离、非 @connect 域名拒绝 (#1477, mv3_utils) - background-script: @background 脚本经 Chrome offscreen 执行,具备 DOM 环境,并通过脚本内 GM 值读写闭环 + mock server probe 做稳定断言 (#1457) - user-config-yaml: 含 __proto__ 的恶意 @userconfig 被拒、原型链未污染 (#1494) - backup-zip: 备份导出/导入 zip 往返(JSZipp generateAsync/loadAsync)(#1479) - e2e waits: 移除固定 sleep/忙等,改为条件等待;并升级 workflow action runtime 版本 - server-fixtures: 共享 fixture + mock server
CodFrm
added a commit
that referenced
this pull request
Jun 12, 2026
为 v1.4.0-beta.3 → beta.4 的核心改动补充 Playwright E2E(复用现有两阶段 userScripts fixture,并新增本地 mock server + host-resolver 域名映射,全程不依赖外网): - resource-update: @require/@resource 注入与读取、24h TTL 同 URL 去重、拉取失败优雅降级、多 require 并发全部加载 (#1193) - gm-xhr-site-access: 跨域 @connect 放行、x-sc-request-marker 经 DNR 剥离、非 @connect 域名拒绝 (#1477, mv3_utils) - background-script: @background 脚本经 Chrome offscreen 执行,具备 DOM 环境,并通过脚本内 GM 值读写闭环 + mock server probe 做稳定断言 (#1457) - user-config-yaml: 含 __proto__ 的恶意 @userconfig 被拒、原型链未污染 (#1494) - backup-zip: 备份导出/导入 zip 往返(JSZipp generateAsync/loadAsync)(#1479) - e2e waits: 移除固定 sleep/忙等,改为条件等待;并升级 workflow action runtime 版本 - server-fixtures: 共享 fixture + mock server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
Description / 描述
Close #1476
修复在浏览器未授予 ScriptCat 对目标站点的访问权限时,脚本发起跨域请求可能出现非预期错误的问题。
本次改动会在处理 GM.xmlHttpRequest / 跨域请求权限确认时,先检查扩展是否已拥有目标 origin 的站点访问权限。如果尚未授权,则在确认页面引导用户通过浏览器权限弹窗授予对应站点访问权限,授权成功后再继续执行请求;如果用户拒绝授权,则本次请求会被拒绝。
主要改动
chrome.permissions.contains的检查。extension-site-access确认类型。chrome.permissions.request,通过用户手势请求站点访问权限。@connect权限判断逻辑,并在已允许 CORS 但缺少站点访问权限时继续请求浏览器站点权限。测试
已验证以下场景:
Screenshots / 截图
DENY
ALLOW
m501a.user.js
m501b.user.js
server.zip