Помимо переопределения console._commandLineAPI, есть несколько других способов проникнуть в InjectedScriptHost в браузерах WebKit, чтобы предотвратить или изменить оценку выражений, введенных в консоль разработчика.
Редактировать:
Chrome исправил это в прошлом выпуске. - что должно было быть до февраля 2015 года, когда я создал суть в то время
Так что вот еще одна возможность. На этот раз мы подключаемся, на уровень выше, напрямую, InjectedScriptа не InjectedScriptHostв отличие от предыдущей версии.
Это довольно приятно, так как вы можете напрямую использовать патч для обезьяны InjectedScript._evaluateAndWrapвместо того, чтобы полагаться на него, InjectedScriptHost.evaluateпоскольку это дает вам более детальный контроль над тем, что должно произойти.
Еще одна довольно интересная вещь заключается в том, что мы можем перехватить внутренний результат при вычислении выражения и вернуть его пользователю вместо нормального поведения.
Вот код, который делает именно это, возвращает внутренний результат, когда пользователь что-то оценивает в консоли.
var is;
Object.defineProperty(Object.prototype,"_lastResult",{
get:function(){
return this._lR;
},
set:function(v){
if (typeof this._commandLineAPIImpl=="object") is=this;
this._lR=v;
}
});
setTimeout(function(){
var ev=is._evaluateAndWrap;
is._evaluateAndWrap=function(){
var res=ev.apply(is,arguments);
console.log();
if (arguments[2]==="completion") {
//This is the path you end up when a user types in the console and autocompletion get's evaluated
//Chrome expects a wrapped result to be returned from evaluateAndWrap.
//You can use `ev` to generate an object yourself.
//In case of the autocompletion chrome exptects an wrapped object with the properties that can be autocompleted. e.g.;
//{iGetAutoCompleted: true}
//You would then go and return that object wrapped, like
//return ev.call (is, '', '({test:true})', 'completion', true, false, true);
//Would make `test` pop up for every autocompletion.
//Note that syntax as well as every Object.prototype property get's added to that list later,
//so you won't be able to exclude things like `while` from the autocompletion list,
//unless you wou'd find a way to rewrite the getCompletions function.
//
return res; //Return the autocompletion result. If you want to break that, return nothing or an empty object
} else {
//This is the path where you end up when a user actually presses enter to evaluate an expression.
//In order to return anything as normal evaluation output, you have to return a wrapped object.
//In this case, we want to return the generated remote object.
//Since this is already a wrapped object it would be converted if we directly return it. Hence,
//`return result` would actually replicate the very normal behaviour as the result is converted.
//to output what's actually in the remote object, we have to stringify it and `evaluateAndWrap` that object again.`
//This is quite interesting;
return ev.call (is, null, '(' + JSON.stringify (res) + ')', "console", true, false, true)
}
};
},0);
Это немного многословно, но я подумала, что добавлю некоторые комментарии
Поэтому обычно, если пользователь, например, оценивает, [1,2,3,4]вы ожидаете следующий результат:
После того, как monkeypatching InjectedScript._evaluateAndWrapоценивает то же самое выражение, выдает следующий вывод:

Как вы видите, маленькая левая стрелка, обозначающая вывод, все еще там, но на этот раз мы получаем объект. Где результат выражения, массив [1,2,3,4]представлен как объект со всеми описанными его свойствами.
Я рекомендую попытаться оценить это и то выражение, в том числе те, которые вызывают ошибки. Это довольно интересно.
Кроме того, взгляните на is - InjectedScriptHost- объект. Он предоставляет некоторые методы, с которыми можно поиграть и получить представление о внутренностях инспектора.
Конечно, вы можете перехватить всю эту информацию и все равно вернуть исходный результат пользователю.
Просто замените оператор возврата в пути else console.log (res)следующим a return res. Тогда вы получите следующее.
Конец Правки
Это предыдущая версия, которая была исправлена Google. Следовательно, это больше невозможно.
Один из них подключается к Function.prototype.call
Chrome оценивает введенное выражение, используя callего функцию eval InjectedScriptHostкакthisArg
var result = evalFunction.call(object, expression);
Учитывая это, вы можете слушать к thisArgиз callсуществ evaluateи получить ссылку на первый аргумент ( InjectedScriptHost)
if (window.URL) {
var ish, _call = Function.prototype.call;
Function.prototype.call = function () { //Could be wrapped in a setter for _commandLineAPI, to redefine only when the user started typing.
if (arguments.length > 0 && this.name === "evaluate" && arguments [0].constructor.name === "InjectedScriptHost") { //If thisArg is the evaluate function and the arg0 is the ISH
ish = arguments[0];
ish.evaluate = function (e) { //Redefine the evaluation behaviour
throw new Error ('Rejected evaluation of: \n\'' + e.split ('\n').slice(1,-1).join ("\n") + '\'');
};
Function.prototype.call = _call; //Reset the Function.prototype.call
return _call.apply(this, arguments);
}
};
}
Например, вы можете выдать ошибку, что оценка была отклонена.

Вот пример, где введенное выражение передается компилятору CoffeeScript перед передачей его evaluateфункции.