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

如何在Tampermonkey的站点脚本中引用已安装的工具脚本?

问题场景与需求

我需要让代码在一个页面以隔离模式运行,在另一个页面的主页面环境运行。为避免本地工具文件误删或移动导致不可用,我把工具代码放在Tampermonkey中,目前已安装三个用户脚本:utility、site A、site B。

utility脚本代码:

// ==UserScript==
// @name         utility
// @namespace    http://sjngm/
// @grant        none
// ==/UserScript==

// 大概是这样的结构
const Utility = {
  func: () => { ... }
};

现在要在site A脚本中加载utility的功能,我尝试了以下代码但无法正常工作:

// ==UserScript==
// @name         site A
// @namespace    http://sjngm/
// @match        http*://site-a.com/*
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
  'use strict';

  // 尝试用这种方式加载,但不行
  GM_xmlhttpRequest({
    method: "GET",
    url: "utility", // 这里是核心问题,找不到脚本
    onload: (e) => {
      console.log(e.responseText);
    }
  });

})();

问题在于这段代码会基于当前页面URL去加载"utility",而我需要直接引用Tampermonkey内部的utility脚本,请问这是否可行?该如何实现?

可行的实现方案

方法1:利用Tampermonkey的@require指令(推荐)

这是最直接的方式,把utility脚本的核心代码单独保存,再在业务脚本中通过@require引入:

  1. 把utility的核心逻辑保存为独立文件,比如utility.js:
const Utility = {
  func: () => { 
    // 你的工具函数逻辑
  }
};
  1. 修改site A脚本的元信息,添加@require指向该文件的本地路径或远程地址:
// ==UserScript==
// @name         site A
// @namespace    http://sjngm/
// @match        http*://site-a.com/*
// @require      file:///C:/Users/你的用户名/Desktop/utility.js  // Windows本地路径示例
// @grant        none
// ==/UserScript==

(function() {
  'use strict';

  // 直接调用Utility对象的方法
  console.log(Utility.func());
})();
  • 本地路径格式:Windows用file:///开头,Linux/macOS用file://开头(如file:///home/xxx/utility.js)。
  • 若担心本地文件丢失,可把utility.js上传到静态托管服务,用远程URL作为@require地址。

方法2:通过Tampermonkey存储共享代码

不想用外部文件的话,可把utility代码存入Tampermonkey的GM存储,其他脚本读取后执行:

  1. 修改utility脚本,添加存储权限并写入代码:
// ==UserScript==
// @name         utility
// @namespace    http://sjngm/
// @grant        GM_setValue
// ==/UserScript==

const utilityCode = `
const Utility = {
  func: () => { 
    // 工具函数逻辑
  }
};
`;

// 将代码存入GM存储
GM_setValue("utilityCode", utilityCode);
  1. 在site A脚本中读取并执行代码:
// ==UserScript==
// @name         site A
// @namespace    http://sjngm/
// @match        http*://site-a.com/*
// @grant        GM_getValue
// ==/UserScript==

(function() {
  'use strict';

  const utilityCode = GM_getValue("utilityCode");
  if (utilityCode) {
    eval(utilityCode);
    // 执行工具函数
    console.log(Utility.func());
  }
})();
  • 注意:eval存在安全风险,确保只有你能修改存储的代码内容。

方法3:脚本间消息通信调用功能

通过Tampermonkey的消息API,让utility脚本响应其他脚本的功能调用请求:

  1. 修改utility脚本,添加消息监听逻辑:
// ==UserScript==
// @name         utility
// @namespace    http://sjngm/
// @grant        GM_addValueChangeListener
// @grant        GM_setValue
// ==/UserScript==

const Utility = {
  func: () => { 
    return "工具函数执行结果";
  }
};

// 监听调用请求
GM_addValueChangeListener("utilityCall", (key, oldVal, newVal, remote) => {
  if (remote && newVal) {
    const { funcName, callbackKey } = newVal;
    const result = Utility[funcName]();
    // 通过回调键返回结果
    GM_setValue(callbackKey, result);
  }
});
  1. 在site A脚本中发送请求并接收结果:
// ==UserScript==
// @name         site A
// @namespace    http://sjngm/
// @match        http*://site-a.com/*
// @grant        GM_setValue
// @grant        GM_addValueChangeListener
// ==/UserScript==

(function() {
  'use strict';

  // 生成唯一回调标识
  const callbackKey = `utilityCallback_${Date.now()}`;

  // 监听结果返回
  GM_addValueChangeListener(callbackKey, (key, oldVal, newVal) => {
    if (newVal) {
      console.log("工具函数返回结果:", newVal);
      // 清理监听与存储
      GM_removeValueChangeListener(callbackKey);
      GM_deleteValue(callbackKey);
    }
  });

  // 发送调用请求
  GM_setValue("utilityCall", {
    funcName: "func",
    callbackKey: callbackKey
  });
})();
  • 这种方式完全在Tampermonkey内部实现,无需外部文件,但逻辑相对复杂。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:53:34