You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改JavaScript中window.location.href会导致Greasemonkey无法关闭窗口吗?

问题解答

1. 权限丢失的原因

没错,就是修改window.location.href导致的——Firefox对window.close()的权限限制非常严格:只有通过脚本主动创建的窗口(比如用window.open()打开的新窗口),创建它的脚本才有资格调用window.close()关闭它。

你当前的窗口是用户手动打开或通过正常网页导航进入的,哪怕页面脚本修改了location.href跳转到应用协议,这个窗口的"创建者"依然不是你的Greasemonkey脚本,所以直接调用window.close()会被浏览器拦截。

2. 实现重定向+关闭窗口的解决方案

核心思路是:绕过原生location跳转,自己触发应用协议,再用技巧获取窗口关闭权限。这里提供两种可行方案:

方案一:拦截原页面的跳转(推荐)

用run-at: document-start让脚本在原页面代码之前运行,拦截它的location.href修改,自己触发应用后关闭窗口:

// ==UserScript==
// @name         启动应用并自动关窗
// @namespace    your-custom-namespace
// @version      0.1
// @description  触发桌面应用后自动关闭当前浏览器窗口
// @match        你的目标网页完整URL
// @run-at       document-start
// @grant        none
// ==/UserScript==

// 拦截window.location.href的设置
const originalSetHref = Object.getOwnPropertyDescriptor(window.location.__proto__, 'href').set;
Object.defineProperty(window.location, 'href', {
  set: function(value) {
    if (value.startsWith('app_protocol://')) {
      // 用隐藏iframe触发应用协议,避免页面跳转
      const triggerFrame = document.createElement('iframe');
      triggerFrame.style.display = 'none';
      triggerFrame.src = value;
      document.documentElement.appendChild(triggerFrame);
      
      // 用技巧绕过关闭权限:模拟脚本创建当前窗口后关闭
      setTimeout(() => {
        window.open('', '_self').close();
      }, 500);
      return;
    }
    // 非应用协议的跳转正常执行
    originalSetHref.call(this, value);
  }
});

方案二:直接触发应用后关闭窗口

如果不需要拦截原页面的跳转,也可以直接在页面加载后自己触发应用,再用同样的关闭技巧:

// ==UserScript==
// @name         启动应用并自动关窗
// @namespace    your-custom-namespace
// @version      0.1
// @description  触发桌面应用后自动关闭当前浏览器窗口
// @match        你的目标网页完整URL
// @run-at       document-idle
// @grant        none
// ==/UserScript==

// 触发应用协议
const triggerFrame = document.createElement('iframe');
triggerFrame.style.display = 'none';
triggerFrame.src = 'app_protocol:///url.code';
document.body.appendChild(triggerFrame);

// 延迟关闭,确保应用启动请求已发送
setTimeout(() => {
  window.open('', '_self').close();
}, 500);

注意事项

  • window.open('', '_self').close()是Firefox上常用的权限绕过技巧,但如果用户浏览器禁用了弹出窗口,这个方法可能失效,需要提醒用户调整对应设置。
  • 延迟时间可以根据实际情况调整(比如300-1000ms),保证应用启动请求已经被浏览器处理,再关闭窗口。

内容的提问来源于stack exchange,提问作者bjb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 15:00:49