我制作了以下 Tampermonkey 用户脚本进行测试,它应该按照注释工作,但事实并非如此。
// ==UserScript==
// @name Test: overriding console.log
// @namespace http://tampermonkey.net/
// @version 0.2
// @description try to take over the world!
// @author You
// @match https://example.com
// @run-at document-idle
// @noframes
// ==/UserScript==
var consoleLog = console.log;
var logs = [];
console.log = function(message) { // Override the console.log function to capture the output
logs.push(message); // Store the message in the logs array
consoleLog.apply(console, ["[Test App] ", ...arguments]); // Call the original console.log function
};
console.log('Hello, world!'); // this would log `[Test App] Hello, world!`
// console.log = consoleLog; // Restore the original console.log function
console.log(logs); // this would log `["Hello, world!"]`
所以,转到
https://example.com/
,打开开发工具控制台选项卡,我看到:
Hello, world!
[]
但是,应该是这样的:
[Test App] Hello, world!
["Hello, world!"]
事实是它在 node.js 或 chrome devtools 控制台上运行良好,所以我对奇怪的行为感到困惑。那么,如何修复呢?谢谢。
嗯,我已经解决了这个问题。这是修改后的脚本:
// ==UserScript==
// @name Test: overriding console.log
// @namespace http://tampermonkey.net/
// @version 0.2
// @description try to take over the world!
// @author You
// @match https://example.com
// @run-at document-idle
// @noframes
// @grant unsafeWindow
// ==/UserScript==
var consoleLog = unsafeWindow.console.log;
var logs = [];
unsafeWindow.console.log = function(message) {
logs.push(message);
consoleLog.apply(unsafeWindow.console, ["[Test App] ", ...arguments]);
};
unsafeWindow.console.log('Hello, world!');
// unsafeWindow.console.log(logs);
Tampermonkey 环境在某种“沙箱”中运行,某些行为可能与常规 JavaScript 上下文不同。
这里的想法是使用 unsafeWindow 来引用页面上下文中的实际全局窗口对象,而不是 Tampermonkey 沙盒版本的窗口。
另外,附注:我不应该这样做
console.log(logs);
,因为它会被困在日志调用本身的循环中。只需在开发工具控制台中logs
就足够了。