[英]Restoring console.log()
For some reason, the prototype framework (or another JavaScript code) that is shipped with Magento is replacing standard console functions, so I can't debug anything. 出于某种原因, Magento附带的原型框架(或其他JavaScript代码)正在取代标准的控制台功能,所以我无法调试任何东西。 Writing down in JavaScript console
console
I get the following output: 在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.112
on Linux. 我在Linux上使用
Google Chrome version 13.0.782.112
。
Prototype JavaScript framework, version 1.6.0.3
Is there a quick way to solve this? 有没有快速解决方法?
Since original console is in window.console object, try restoring window.console
from iframe
: 由于原始控制台位于window.console对象中,请尝试从
iframe
恢复window.console
:
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。
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] }
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() {}
}
delete window.console
restores the original console
object in Firefox and Chrome. delete window.console
恢复Firefox和Chrome中的原始console
对象。
How does this work? 这是如何运作的?
window
is 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 window
instance, but it doesn't corrupt window.prototype
. 外部库/框架(或Firebug等)的一些愚蠢的开发人员覆盖
window
实例的属性控制台,但它不会破坏window.prototype
。 By the delete
operator we are back dispatching from the console.*
methods to prototype code. 通过
delete
运算符,我们将从console.*
调用console.*
方法到原型代码。
Save a reference to the original console
in a variable at the very start of the script and then either use this reference, or redefine console
to 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");
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.
我没有回复Xaerxess的原始答案,因为我没有足够的声誉去做。 Looks like that is the correct answer, but for some reason I notice sometimes it works in my software and sometimes not...
看起来这是正确的答案,但出于某种原因,我注意到它有时在我的软件中有效,有时不...
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. 谢谢大家。
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. 唯一一个(有点)工作是从@Xaerxess告诉的
<iframe>
抓住控制台。
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;
},
});
}
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上测试过
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.