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
Restoring console.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 console
I 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.112
on 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.console
from iframe
:
由于原始控制台在 window.console 对象中,请尝试window.console
从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);
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.console
restores the original console
object in Firefox and Chrome.
delete window.console
console
在 Firefox 和 Chrome 中恢复原始对象。
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
. By the delete
operator 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 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");
回答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;
},
});
}