如何用Tampermonkey在JavaScript中伪造系统时间?
解决Tampermonkey在Firefox中伪造系统时间失效的问题
原脚本的核心问题有两个:一是未覆盖Date的所有调用场景(包括带参构造、Date.now()这类静态方法),二是脚本运行时机太晚,页面已有代码提前获取了原生Date对象,导致覆盖无效。以下是修复后的完整解决方案:
改进后的伪造时间脚本
// ==UserScript== // @name 全局伪造系统时间 // @namespace fake-date-script // @version 2.0 // @description 在浏览器中全局伪造系统时间,支持Firefox最新版 // @match http://*/* // @match https://*/* // @run-at document-start // 关键:在页面脚本加载前执行 // @grant none // ==/UserScript== (function() { 'use strict'; // 定义要伪造的目标时间(可自行修改) const FAKE_TIMESTAMP = new Date('2022-01-01T00:00:00.000Z').getTime(); // 保存原生Date对象,避免无限递归 const OriginalDate = window.Date; // 自定义FakeDate类,覆盖所有构造场景 class FakeDate extends OriginalDate { constructor(...args) { // 根据参数数量处理不同构造逻辑 if (args.length === 0) { super(FAKE_TIMESTAMP); } else { // 带参数时,基于伪造时间计算偏移(可选:也可以直接返回固定时间) // 如果需要完全固定时间,不管参数都返回FAKE_TIMESTAMP,替换为super(FAKE_TIMESTAMP)即可 super(...args); } } // 覆盖静态方法Date.now() static now() { return FAKE_TIMESTAMP; } // 可选:覆盖Date.parse(),确保解析时间也基于伪造逻辑 static parse(...args) { const result = OriginalDate.parse(...args); // 如果需要让解析后的时间也偏移,可自行调整,这里保持原生逻辑 return result; } // 可选:覆盖Date.UTC() static UTC(...args) { return OriginalDate.UTC(...args); } } // 强制覆盖window.Date,确保不可被篡改 Object.defineProperty(window, 'Date', { value: FakeDate, writable: false, enumerable: true, configurable: false }); })();
关键修复点说明
@run-at document-start:必须添加这个指令,让脚本在页面所有资源和脚本加载前执行,确保页面代码获取的是伪造后的Date对象,而非原生对象。- 覆盖所有
Date调用场景:不仅处理无参的new Date(),还支持带参数的构造方式,同时重写了Date.now()这个常用的获取时间戳方法。 - 防止
Date被恢复:用Object.defineProperty将伪造的Date设置为不可写、不可配置,避免页面脚本重新覆盖回原生Date。
可选调整
如果需要完全固定时间,不管任何Date构造参数都返回伪造的时间,只需修改FakeDate的构造函数:
constructor(...args) { super(FAKE_TIMESTAMP); }
这样不管是new Date()、new Date(123456789)还是new Date('2023-10-01'),都会返回设定的伪造时间。
内容的提问来源于stack exchange,提问作者Jack Ma
相关产品推荐
相关产品推荐

