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

如何编写Greasemonkey4.11脚本修改JS源码适配Firefox78私有字段?

问题

老旧的Firefox 78不支持JavaScript「私有字段(private fields)」,但部分现代网站的JavaScript代码未做兼容降级就使用该特性。例如以下代码:

if (o.userAgentDataBuilder) {
  const v = new class NavigatorUAData {
    #p;

    constructor({p, ua}) {
      this.#p = p;

运行时会触发错误:

Uncaught SyntaxError: private fields are not currently supported

已能通过Greasemonkey修改页面HTML,但不清楚如何修改JavaScript源码。请问能否编写Greasemonkey 4.11用户脚本,将JavaScript私有字段转为非私有字段,使这类现代JS代码能在Firefox78中正常运行?

解决方案
  • 核心思路:通过Greasemonkey拦截页面加载的JavaScript文件,将代码中以#开头的私有字段替换为常规非私有属性,再把修改后的代码注入页面执行,同时阻止原脚本的默认加载逻辑。

  • 具体脚本实现:
    以下是适配Firefox 78的Greasemonkey 4.11用户脚本:

    // ==UserScript==
    // @name        私有字段转非私有兼容脚本
    // @namespace   private-field-polyfill
    // @match       *://*/*
    // @grant       GM.xmlHttpRequest
    // @grant       GM.addElement
    // @run-at      document-start
    // @connect     *
    // ==/UserScript==
    
    // 拦截所有外部脚本加载
    document.addEventListener('beforescriptexecute', function(e) {
      const targetScript = e.target;
      // 跳过内联脚本(如需处理内联可扩展逻辑)
      if (!targetScript.src) return;
    
      // 阻止原脚本执行
      e.preventDefault();
    
      // 请求获取原脚本内容
      GM.xmlHttpRequest({
        method: 'GET',
        url: targetScript.src,
        onload: function(res) {
          let modifiedCode = res.responseText;
    
          // 替换类中的私有字段定义(如 #p; → this.p;)
          modifiedCode = modifiedCode.replace(/^\s*#(\w+);/gm, '  this.$1;');
          // 替换类中对私有字段的引用(如 this.#p → this.p)
          modifiedCode = modifiedCode.replace(/this\.#(\w+)/g, 'this.$1');
    
          // 创建新脚本注入页面
          const newScript = GM.addElement(document.head, 'script', {
            textContent: modifiedCode,
            type: 'text/javascript'
          });
          newScript.dispatchEvent(new Event('load'));
        }
      });
    });
    
  • 注意事项:

    • 脚本设置document-start运行时机,确保在页面脚本加载前完成拦截。
    • 当前正则仅处理基础私有字段场景,若遇到私有方法、私有访问器等复杂语法,需要扩展正则规则。
    • 部分网站存在CORS限制时,@connect *可允许跨域请求脚本内容。
    • 内联脚本的处理需额外逻辑,可在DOMContentLoaded后遍历页面内联脚本进行替换,但要注意执行顺序问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:46:19