Javascript 正在还原console.log()
出于某种原因,随附的原型框架(或其他JavaScript代码)正在取代标准控制台函数,因此我无法调试任何东西。在JavaScript控制台Javascript 正在还原console.log(),javascript,google-chrome,prototypejs,console.log,Javascript,Google Chrome,Prototypejs,Console.log,出于某种原因,随附的原型框架(或其他JavaScript代码)正在取代标准控制台函数,因此我无法调试任何东西。在JavaScript控制台console中写下,我得到以下输出: > console Object assert: function () {} count: function () {} debug: function () {} dir: function () {} dirxml: function () {} error: function () {} group: fu
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 () {}
我正在Linux上使用Google Chrome 13.0.782.112版
原型JavaScript框架,版本1.6.0.3
有没有快速的方法解决这个问题?在脚本的最开始将对原始
控制台的引用保存在变量中,然后使用此引用,或者重新定义控制台
以指向捕获的值
例如:
var c = window.console;
window.console = {
log :function(str) {
alert(str);
}
}
// alerts hello
console.log("hello");
// logs to the console
c.log("hello");
由于原始控制台位于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);
在Chrome 14上对我有效。例如
delete console.log
还将还原控制台.log
:
console.log = null;
console.log; // null
delete console.log;
console.log; // function log() { [native code] }
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() {}
}
if(!(“控制台”在窗口中)| |!(“firebug”在控制台中))
{
变量名称=[“日志”、“调试”、“信息”、“警告”、“错误”、“断言”、“目录”、“dirxml”,
“组”、“组结束”、“时间”、“时间结束”、“计数”、“跟踪”、“配置文件”、“配置文件结束”];
window.console={};
对于(变量i=0;i
删除窗口。console
恢复Firefox和Chrome中原始的console
对象
这是怎么回事<代码>窗口
是一个托管对象,通常在所有实例之间使用公共原型实现(浏览器中有许多选项卡)
外部库/框架(或等)的一些愚蠢的开发人员重写
窗口
实例的属性控制台,但它不会损坏窗口。原型
。通过delete
操作符,我们从控制台返回调度。*
方法到原型代码。此问题中给出的解决方案在新浏览器中不再正确解决此问题。唯一有效的方法是从@Xaerxess告诉我们的
抓取控制台
我编写了一个用户脚本来保护控制台不被覆盖。它不会破坏任何重写控制台的工具——它同时调用重写的方法和原始方法。当然,它也可以包含在网页中
// ==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;
},
});
}
在Chrome 71和Firefox 65上测试,以防有人面临同样的情况。 我没有回复Xaerxess的原始答案,因为我没有足够的声誉来做这件事。 看起来这是正确的答案,但出于某种原因,我注意到它有时在我的软件中工作,有时不工作 因此,我尝试在运行脚本之前完成删除操作,看起来所有操作都100%正常
if(!(“控制台”在窗口中)| |!(“firebug”在控制台中))
{
console.log=null;
console.log;//null
删除console.log;
//Xaerxess原创
var i=document.createElement('iframe');
i、 style.display='none';
文件.正文.附件(一);
window.console=i.contentWindow.console;
}
看看Magento在这方面似乎有一个开放的问题:是的,似乎我有这个问题,但我不打算更改Magento代码,对于dev,我同意接受的解决方案。当然我可以做到,在一切开始之前注入一些JS,我确信这个解决方案可以工作,但是我想要一个快速解决问题的方法。谢谢你,是的!这样更好!这就是我喜欢stackoverflow的原因:D@Shoan:在Chrome 26中适用于我。请尝试删除窗口。控制台在Chrome 30.x中适用于我;在Chrome 52中不再工作。可以在Twitter上测试,例如:console.log
->function(){}
,删除console.log或window.console.log只会将其删除,而不会恢复原始行为。以下技巧可能有助于Chrome在使用delete console.log
时不恢复本机日志功能。。。如果您愿意安装(或已经安装)TamperMonkey,那么您只需要一个简单的脚本<代码>设置超时(()=>{unsafeWindow.console=window.console;},2000)
Tampermonkey脚本获得自己的窗口
对象副本,因此您需要做的就是在延迟后恢复原始控制台对象。根据需要调整。。。(请确保您删除了默认的/@grant none
)。对于要使用此功能的任何人,请记得自己清理。AKA:i.parentNode.removeChild(i)
这个答案在当前版本的Chrome(52+)中确实有效,而被接受的答案却不行。这是我见过的最有创意的答案!谢谢。@nickload在上次i.parentNode.removeChild(i)
之后它仍然有效,不是吗?我使用的是Chrome 63(金丝雀色),这个答案有效,但没有行i.parentNode.removeChild(i)代码>。这与@Xaerxess的答案相同,如果你查看他的答案的评论,你会发现新Chrome版本的警告。。。您可以只更新他的答案,也可以更新注释,无需重复。@balexandre不一样,因为此函数不删除子项,如果您不删除仍在工作的子项,则控制台不会打印任何内容:)仅因为您更改了一行代码,就不应该是新答案。。。Stackoverflow不是为了衡量如何编写更好的代码,而是为了帮助下一个用户快速获得正确的答案。这难道不是现在公认的答案吗?因为最初公认的答案在最新的Chrome或Firefox上不再适用了?这对我来说很有效。仅仅执行delete console.log操作不起作用,因此这应该是可以接受的答案。
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
}