javascript 恢复 console.log()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7089443/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 22:56:28  来源:igfitidea点击:

Restoring console.log()

javascriptgoogle-chromeprototypejsconsole.log

提问by s3v3n

For some reason, the prototype framework (or another JavaScript code) that is shipped with Magentois replacing standard console functions, so I can't debug anything. Writing down in JavaScript console consoleI get the following output:

出于某种原因,Magento附带的原型框架(或其他 JavaScript 代码)正在替换标准控制台功能,因此我无法调试任何东西。在 JavaScript 控制台中写下console我得到以下输出:

> console
Object
assert: function () {}
count: function () {}
debug: function () {}
dir: function () {}
dirxml: function () {}
error: function () {}
group: function () {}
groupEnd: function () {}
info: function () {}
log: function () {}
profile: function () {}
profileEnd: function () {}
time: function () {}
timeEnd: function () {}
trace: function () {}
warn: function () {}

I'm using Google Chrome version 13.0.782.112on Linux.

Google Chrome version 13.0.782.112在 Linux 上使用。

Prototype JavaScript framework, version 1.6.0.3

Prototype JavaScript framework, version 1.6.0.3

Is there a quick way to solve this?

有没有快速解决这个问题的方法?

采纳答案by pimvdb

For example,

例如,

delete console.log

would also restore console.log:

也会恢复console.log

console.log = null;
console.log;         // null

delete console.log;
console.log;         // function log() { [native code] }

回答by Xaerxess

Since original console is in window.console object, try restoring window.consolefrom iframe:

由于原始控制台在 window.console 对象中,请尝试window.consoleiframe以下位置恢复:

var i = document.createElement('iframe');
i.style.display = 'none';
document.body.appendChild(i);
window.console = i.contentWindow.console;
// with Chrome 60+ don't remove the child node
// i.parentNode.removeChild(i);

Works for me on Chrome 14.

在 Chrome 14 上对我有用。

回答by Francis Kim

Magento has the following code in /js/varien/js.js- comment it out & it will work.

Magento 中有以下代码/js/varien/js.js- 将其注释掉并且它会起作用。

if (!("console" in window) || !("firebug" in console))
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}

回答by gavenkoa

delete window.consolerestores the original consoleobject in Firefox and Chrome.

delete window.consoleconsole在 Firefox 和 Chrome 中恢复原始对象。

How does this work? windowis a hosted object and usually it is implemented with a common prototype between all instances (you have many tabs in the browser).

这是如何运作的?window是一个托管对象,通常它是通过所有实例之间的通用原型实现的(浏览器中有许多选项卡)。

Some dumb developers of external libraries/frameworks (or Firebug, etc.) override property console of the windowinstance, but it doesn't corrupt window.prototype. By the deleteoperator we are back dispatching from the console.*methods to prototype code.

外部库/框架(或Firebug等)的一些愚蠢的开发人员会覆盖window实例的属性控制台,但它不会损坏window.prototype. 通过delete操作符,我们从console.*方法返回到原型代码。

回答by OnTheFly

Just in case that someone face this same situation. I did not replied to the original answer for Xaerxess because I don't have enough reputation to do it.Looks like that is the correct answer, but for some reason I notice sometimes it works in my software and sometimes not...

以防万一有人面临同样的情况。 我没有回复 Xaerxess 的原始答案,因为我没有足够的声誉来做到这一点。看起来这是正确的答案,但出于某种原因,我注意到有时它在我的软件中有效,有时却不起作用......

So I tried completing deleting before running the script and looks like everything is working fine 100% of times.

所以我尝试在运行脚本之前完成删除,看起来一切正常 100%。

if (!("console" in window) || !("firebug" in console))
{

  console.log = null;
  console.log;         // null

  delete console.log;

  // Original by Xaerxess
  var i = document.createElement('iframe');
  i.style.display = 'none';
  document.body.appendChild(i);
  window.console = i.contentWindow.console;

}

Thank you to everybody.

谢谢大家。

回答by Russ Cam

Save a reference to the original consolein a variable at the very start of the script and then either use this reference, or redefine consoleto point to the captured value.

console在脚本一开始就在变量中保存对原始引用的引用,然后使用此引用或重新定义console以指向捕获的值。

Example:

例子:

var c = window.console;

window.console = {
    log :function(str) {
        alert(str);
    }
}

// alerts hello
console.log("hello");

// logs to the console
c.log("hello");

回答by Marco Cesarato

function restoreConsole() {
  // Create an iframe for start a new console session
  var iframe = document.createElement('iframe');
  // Hide iframe
  iframe.style.display = 'none';
  // Inject iframe on body document
  document.body.appendChild(iframe);
  // Reassign the global variable console with the new console session of the iframe 
  console = iframe.contentWindow.console;
  window.console = console;
  // Don't remove the iframe or console session will be closed
}

Tested on Chrome 71 and Firefox 65

在 Chrome 71 和 Firefox 65 上测试

回答by Tomá? Zato - Reinstate Monica

The solutions given in this question no longer solve this problem correctly in new browsers. The only one that (sort of) work is grasping the console from an <iframe>as told by @Xaerxess.

此问题中给出的解决方案在新浏览器中不再正确解决此问题。<iframe>正如@Xaerxess 所说,唯一(某种)工作是从控制台中获取控制台。

I wrote an userscript that protects console from being overwritten. It doesn't break any tools that override the console - it calls both the overridden and original methods. It can of course also be included in web-page.

我写了一个用户脚本来保护控制台不被覆盖。它不会破坏任何覆盖控制台的工具——它同时调用被覆盖的方法和原始方法。它当然也可以包含在网页中。

// ==UserScript==
// @name        Protect console
// @namespace   util
// @description Protect console methods from being overriden
// @include     *
// @version     1
// @grant       none
// @run-at      document-start
// ==/UserScript==
{

    /**
      * This object contains new methods assigned to console.
      * @type {{[x:string]:Function}} **/
    const consoleOverridenValues = {};
    /**
      * This object contains original methods copied from the console object
      * @type {{[x:string]:Function}} **/
    const originalConsole = {};
    window.originalConsole = originalConsole;
    // This is the original console object taken from window object
    const originalConsoleObject = console;
    /**
     * 
     * @param {string} name
     */
    function protectConsoleEntry(name) {
        const protectorSetter = function (newValue) {
            originalConsole.warn("Someone tried to change console." + name + " to ", newValue);
            consoleOverridenValues[name] = function () {
                /// call original console first
                originalConsole[name].apply(originalConsoleObject, arguments);
                if (typeof newValue == "function") {
                    /// call inherited console
                    newValue.apply(window.console, arguments);
                }
            }
        }
        const getter = function () {
            if (consoleOverridenValues[name])
                return consoleOverridenValues[name];
            else
                return originalConsole[name];
        }
        Object.defineProperty(console, name, {
            enumerable: true,
            configurable: false,
            get: getter,
            set: protectorSetter
        });
    }

    /*
     *** This section contains window.console protection
     *** It mirrors any properties of newly assigned values
     *** to the overridenConsoleValues
     *** so that they can be used properly
    */

    /** 
      * This is any new object assigned to window.console
      * @type {Object} **/
    var consoleOverridenObject = null;
    /// Separate boolean is used instead
    /// of checking consoleOverridenObject == null
    /// This allows null and undefined to be assigned with 
    /// expected result
    var consoleIsOverriden = false;

    for (var i in console) {
        originalConsole[i] = console[i];
        protectConsoleEntry(i);
    }

    Object.defineProperty(window, "console", {
        /// always returns the original console object
       /// get: function () { return consoleIsOverriden ? consoleOverridenObject : originalConsoleObject; },
        get: function () { return originalConsoleObject; },
        set: function (val) {
            originalConsole.log("Somebody tried to override window.console. I blocked this attempt."
                + " However the emulation is not perfect in this case because: \n"
                + "     window.console = myObject;\n"
                + "     window.console == myObject\n"
                + "returns false."
            )
            consoleIsOverriden = true;
            consoleOverridenObject = val;

            for (let propertyName in val) {
                consoleOverridenValues[propertyName] = val[propertyName];
            }
            return console;
        },
    });
}