何らかの理由で、 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 () {}
LinuxではGoogle Chrome version 13.0.782.112
を使用しています。
Prototype JavaScript framework, version 1.6.0.3
これを解決する簡単な方法はありますか?
例えば、
delete console.log
console.log
も復元します:
console.log = null;
console.log; // null
delete console.log;
console.log; // function log() { [native code] }
元のコンソールは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。
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
は、FirefoxとChromeで元のconsole
オブジェクトを復元します。
これはどのように作動しますか? window
はホストされるオブジェクトであり、通常はすべてのインスタンス間で共通のプロトタイプを使用して実装されます(ブラウザーには多くのタブがあります)。
外部ライブラリ/フレームワーク(または Firebug など)の愚かな開発者は、window
インスタンスのプロパティコンソールをオーバーライドしますが、window.prototype
は破損しません。 delete
演算子により、console.*
メソッドからプロトタイプコードにディスパッチします。
スクリプトの開始時に、元のconsole
への参照を変数に保存してから、この参照を使用するか、console
を再定義して、取得した値をポイントします。
例:
var c = window.console;
window.console = {
log :function(str) {
alert(str);
}
}
// alerts hello
console.log("hello");
// logs to the console
c.log("hello");
誰かが同じ状況に直面した場合に備えて。 Xaerxessの元の回答には返信がありませんでした。十分な評判がないためです。これは正しい回答のようですが、何らかの理由で自分のソフトウェアで動作し、時々そうではない...
そのため、スクリプトを実行する前に削除を完了してみましたが、すべてが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;
}
皆様ありがとうございました。
この質問で与えられた解決策は、新しいブラウザでこの問題を正しく解決しません。 @Xaerxessが言うように、(一種の)作業がコンソールを<iframe>
から把握することだけです。
コンソールが上書きされないように保護するユーザースクリプトを作成しました。コンソールをオーバーライドするツールを壊すことはありません-オーバーライドされたメソッドと元のメソッドの両方を呼び出します。もちろん、ウェブページに含めることもできます。
// ==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
}
Chrome 71およびFirefox 65でテスト済み