Skip to content

[BUG] 缺少扩展站点访问权限时 GM_xmlhttpRequest 跨域请求会出现非预期错误 #1476

@cyfung1031

Description

@cyfung1031

问题描述

当脚本使用 GM.xmlHttpRequest / GM_xmlhttpRequest 访问目标站点,且浏览器尚未授予 ScriptCat 扩展对该目标站点的“站点访问权限”时,请求可能会直接进入浏览器侧的 CORS / 预检拦截流程,并出现非预期错误。

该问题容易被误认为是脚本缺少 @connect 授权,或是“脚本设置 > 授权管理”中的跨域授权配置不正确;但实际还存在一层浏览器扩展的站点访问权限。如果该权限缺失,即使脚本侧已经声明并授权了目标域名,跨域请求仍可能失败。

相关场景包括但不限于:

  • GM_xmlhttpRequest 访问 http://localhost:<port>/...
  • 脚本已配置 @connect localhost
  • ScriptCat 内部已经允许跨域访问
  • 但浏览器没有授予 ScriptCat 扩展访问该目标站点的权限

重现步骤

  1. 使用一个脚本调用 GM_xmlhttpRequestGM.xmlHttpRequest 访问目标站点,例如:
GM_xmlhttpRequest({
  url: "http://localhost:23456/config",
  method: "GET",
  onload: (res) => {
    console.log("res:", res);
  },
  onerror: (e) => {
    console.error(e);
  },
});
  1. 在脚本中添加对应的 @connect,例如:
// @connect localhost
  1. 在 ScriptCat 的脚本授权管理中允许对应跨域请求。

  2. 确保浏览器尚未授予 ScriptCat 扩展访问该目标站点的站点访问权限。

  3. 运行脚本并观察请求结果。

实际结果

请求可能失败,并出现类似 CORS / preflight 相关错误,例如:

Access to XMLHttpRequest at 'http://localhost:xxxx/...' from origin 'chrome-extension://...' has been blocked by CORS policy

或者由于浏览器扩展站点访问权限缺失,导致请求流程进入非预期的确认、拒绝或异常状态。

预期结果

当 ScriptCat 检测到目标站点缺少浏览器扩展的站点访问权限时,应当:

  1. 在发起 GM.xmlHttpRequest / GM_xmlhttpRequest 跨域请求前检测扩展是否已拥有目标站点访问权限;
  2. 如果缺少权限,应弹出明确的确认提示,说明需要授予 ScriptCat 对该目标站点的访问权限;
  3. 通过用户手势调用 chrome.permissions.request({ origins }) 请求权限;
  4. 用户授权后继续请求;
  5. 用户拒绝时应按一次性拒绝处理,不应错误地记录为“临时允许”或“永久允许”对应的状态。

影响范围

  • 使用 GM.xmlHttpRequest / GM_xmlhttpRequest 的跨域请求
  • 浏览器扩展站点访问权限未授予的目标站点
  • 从 Tampermonkey 迁移到 ScriptCat 的脚本可能更容易遇到该问题
  • localhost / 带端口的本地服务访问场景较容易复现

相关问题

补充信息

该问题不应仅归类为 @connect 或 ScriptCat 内部跨域授权配置问题。浏览器扩展自身的站点访问权限是额外的一层限制,需要在请求前显式检测,并在缺少权限时引导用户授权。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions