web-dev-qa-db-fra.com

Restauration de console.log ()

Pour une raison quelconque, le prototype de structure (ou un autre code JavaScript) fourni avec Magento remplace les fonctions de console standard, je ne peux donc rien déboguer. Ecrire dans la console JavaScript console Je reçois le résultat suivant:

> 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 () {}

J'utilise Google Chrome version 13.0.782.112 sur Linux.

Prototype JavaScript framework, version 1.6.0.3

Y a-t-il un moyen rapide de résoudre ce problème?

44
s3v3n

Par exemple,

delete console.log

serait également restaurer console.log:

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

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

Comme la console d'origine est dans l'objet window.console, essayez de restaurer window.console à partir de iframe:

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);

Fonctionne pour moi sur Chrome 14.

56
Xaerxess

Magento a le code suivant dans /js/varien/js.js - commentez-le et cela fonctionnera.

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() {}
}
12
Francis Kim

delete window.console restaure l'objet console d'origine dans Firefox et Chrome.

Comment cela marche-t-il? window est un objet hébergé et est généralement implémenté avec un prototype commun à toutes les instances (vous avez plusieurs onglets dans le navigateur).

Certains développeurs stupides de bibliothèques/frameworks externes (ou Firebug , etc.) remplacent la console de propriétés de l'instance window, mais ils ne corrompent pas window.prototype. Par l'opérateur delete, nous renvoyons les méthodes console.* au code prototype.

7
gavenkoa

Enregistrez une référence à la console originale dans une variable au tout début du script, puis utilisez cette référence ou redéfinissez console pour qu'il pointe vers la valeur capturée.

Exemple:

var c = window.console;

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

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

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

Les solutions données dans cette question ne résolvent plus ce problème correctement dans les nouveaux navigateurs. Le seul qui fonctionne (en quelque sorte) est de saisir la console à partir d'un <iframe>, comme le dit @Xaerxess.

J'ai écrit un script utilisateur qui protège la console contre tout écrasement. Il ne casse aucun outil qui remplace la console - il appelle à la fois les méthodes écrasées et originales. Bien entendu, il peut également être inclus dans une page Web.

// ==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;
        },
    });
}
0
Tomáš Zato
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
}

Testé sur Chrome 71 et Firefox 65 

0
Marco Cesarato