Есть ли способ обойти сайт (и), нарушающий console.log

Вывод моей консоли Chrome DevTools:

Navigated to https://twitter.com/
console.log.toString();
"function (){}"
Navigated to http://linuxfr.org/
console.log.toString();
"function log() { [native code] }"

Мне удалось ввести код в основной фрейм twitter.com, используя расширение Chrome, но мне было трудно понять, почему мой код, похоже, не запускался. Похоже, что мой код работает нормально, кроме console.log ничего не получается!

Вопрос: есть ли способ называть "now gone" console.log "native code"?

(замечания о том, что поведение JavaScript "WAT" убрано, вроде)

Ответ 1

Поскольку это расширение Chrome, вы устанавливаете свой контент script на run_at: "document_start" - вы можете (теоретически) "захватить" console.log/error/dir/info и т.д., прежде чем твиттер получит его грязные руки на них

на самом деле, ЗНАЮ, что твиттер заменяет только журнал, предупреждение, информацию, ошибку, вы можете просто сделать:

var _console = ['log', 'warn', 'info', 'error'].reduce(function(result, key) { 
    result[key] = console[key].bind(console); 
    return result
}, {});

то вы можете использовать _console.log и друзей

Ответ 2

Насколько я знаю, это зависит от того, как была выполнена глубокая замена. Например, если бы это было похоже

 console.log = function () {};

Исходная нативная функция log все еще находится в прототипе. Вы можете получить доступ к нему с помощью свойства __proto__ или Object.getPrototypeOf.

console.log = null
Object.getPrototypeOf(console).log
//log() { [native code] }

Также вы можете просто удалить замену из исходного объекта консоли

delete console.log
//true
console.log
//log() { [native code] }

Но весь выше код не будет работать, если я заменил функцию журнала, подобную этой

console.__proto__.__proto__.log = function () {}

И, к сожалению, я не знаю обходного пути для этого случая.

Ответ 3

Основываясь на обсуждении выше и @JaromandaX и JavaScript: The Definitive Guide ниже - один простой polyfill.

function log() {
    if (location.hostname === 'twitter.com'){
        Object.getPrototypeOf(console).log.apply(console, arguments);
    } else {
        console.log.apply(console, arguments);
    }
}