Решения, приведенные в этом вопросе, больше не решают эту проблему правильно в новых браузерах.Единственное, что (вроде) работает, это захват консоли от <iframe>
, как сказал @ 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;
},
});
}