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?
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] }
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.
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() {}
}
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.
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");
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;
},
});
}
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