Javascript 在Chrome中拦截对console.log的调用

Javascript 在Chrome中拦截对console.log的调用,javascript,debugging,console,Javascript,Debugging,Console,我有一个无法更改的脚本,它会进行大量的console.log调用。如果调用包含某些字符串,我想添加另一层并进行响应。这在Firefox中起作用,但在Chrome的第4行抛出一个“非法调用””错误: var oldConsole = {}; oldConsole.log = console.log; console.log = function (arg) { oldConsole.log('MY CONSOLE!!'); oldConsole.log(arg); } 你知道怎么

我有一个无法更改的脚本,它会进行大量的
console.log
调用。如果调用包含某些字符串,我想添加另一层并进行响应。这在Firefox中起作用,但在Chrome的第4行抛出一个“
非法调用”
”错误:

var oldConsole = {};
oldConsole.log = console.log;
console.log = function (arg) {
    oldConsole.log('MY CONSOLE!!');
    oldConsole.log(arg);
}

你知道怎么避开吗?我还尝试克隆控制台…

您需要在chrome的
控制台
上下文中调用
控制台.log

(function () {
  var log = console.log;
  console.log = function () {
    log.call(this, 'My Console!!!');
    log.apply(this, Array.prototype.slice.call(arguments));
  };
}());

现代语言功能可以显著简化此代码段:

{
  const log = console.log.bind(console)
  console.log = (...args) => {
    log('My Console!!!')
    log(...args)
  }
}

您也可以使用相同的逻辑,但在console对象中调用它,以便上下文相同

if(window.console){
  console.yo = console.log;
  console.log = function(str){
    console.yo('MY CONSOLE!!');
    console.yo(str);
  }
}

使用ES6新的扩展运算符,您可以这样编写

(function () {
  var log = console.log;
  console.log = function () {
    log.call(this, 'My Console!!!', ...arguments);
  };
}());

我知道这是一篇老文章,但它还是有用的,因为其他解决方案与旧浏览器不兼容

您可以重新定义控制台(以及所有浏览器)的每个功能的行为,如下所示:

// define a new console
var console = (function(oldCons){
    return {
        log: function(text){
            oldCons.log(text);
            // Your code
        },
        info: function (text) {
            oldCons.info(text);
            // Your code
        },
        warn: function (text) {
            oldCons.warn(text);
            // Your code
        },
        error: function (text) {
            oldCons.error(text);
            // Your code
        }
    };
}(window.console));

//Then redefine the old console
window.console = console;
可以简单地说:

console.log=(m)=>terminal.innerHTML=JSON.stringify(m)
#终端{背景:黑色;颜色:黄绿色}
$>

3V3L 3V3L 3V3L
由于我还不能对@ludovic feltz answer发表评论,以下是他的答案,已更正为允许在控制台中插入字符串:

// define a new console
var console = (function(oldCons){
    return {
        log: function(...text){
            oldCons.log(...text);
            // Your code
        },
        info: function (...text) {
            oldCons.info(...text);
            // Your code
        },
        warn: function (...text) {
            oldCons.warn(...text);
            // Your code
        },
        error: function (...text) {
            oldCons.error(...text);
            // Your code
        }
    };
}(window.console));

//Then redefine the old console
window.console = console;

要完全拦截控制台,我们可以覆盖所有方法:

const bindConsole=function(onMessage){
    Object.keys(console)
    .filter(type=>typeof(console[type])==='function')// *1
    .forEach(type=>{
        let _old=console[type];
        console[type] = function (...args) {
            _old.apply(console,args);
            onMessage(type,args);// *2
        };
    });
};
对于旧浏览器:

var bindOldConsole=function(onMessage){
    for(var k in console){// *1
        if(typeof(console[k])=='function')(function(type){
            var _old=console[type];
            console[type] = function () {
                _old.apply(console,arguments);
                onMessage(type,arguments);
            };
        })(k);
    }
};

  • *1看起来控制台只有方法,但最好确定

  • *2您可以通过将此行替换为以下内容来阻止从消息到控制台的循环调用:

if(!isCyclic())onMessage(type,args)


美好的我一直在找这样的东西。这可以用来修饰javascript中的任何函数吗?@Shane,这是拦截函数调用的基本模式,但是我建议不要使用它,除非绝对必要。直接修改函数或使用OOP概念要好得多。在构建一个有大量运行时组件组装的框架时,这将是一个方便的工具,用于外部驱动的方法来调试组件或使用插件修改现有组件等。这种方法会影响性能吗?只是想知道缺点是什么。我不会修改内部函数,只会修改框架组件方法。您调用的每个函数都会“影响性能”,但偶尔触发异步JavaScript不会明显停滞。看起来函数链接速度明显更快。刚刚做了个测试。对于这类问题,我看到的最清晰的答案是:你怎么能推翻它?
// es6. Not sure concerning old browsers :(
const isCyclic=function (){
    let erst=(new Error()).stack.split('\n');
    return erst.includes(erst[1],2);
};