재정의 외에도 console._commandLineAPI
WebKit 브라우저에서 InjectedScriptHost를 침입하여 개발자 콘솔에 입력 된 표현식의 평가를 방지하거나 변경하는 다른 방법이 있습니다.
편집하다:
Chrome은 지난 릴리스에서이 문제를 해결했습니다. -당시 요점을 만들었으므로 2015 년 2 월 이전에 있었어야합니다.
여기 또 다른 가능성이 있습니다. 이번에 는 이전 버전이 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]
가 다음과 같은 결과를 기대하면 평가 합니다.
InjectedScript._evaluateAndWrap
매우 동일한 표현을 평가하는 monkeypatching 후 다음과 같은 결과가 나타납니다.
보시다시피 출력을 나타내는 작은 왼쪽 화살표가 여전히 있지만 이번에는 객체를 얻습니다. 식의 결과에서 배열 [1,2,3,4]
은 모든 속성이 설명 된 개체로 나타납니다.
오류를 생성하는 표현식을 포함하여이 표현식과 해당 표현식을 평가하는 것이 좋습니다. 꽤 흥미 롭습니다.
또한, 한 번 봐 걸릴 is
- InjectedScriptHost
- 객체. 인스펙터의 내부를 가지고 약간의 통찰력을 얻는 방법을 제공합니다.
물론 모든 정보를 가로 채어 원래 결과를 사용자에게 반환 할 수 있습니다.
else 경로의 return 문을 console.log (res)
다음으로 대체하십시오 return res
. 그런 다음 다음과 같이 끝납니다.
편집 끝
이것은 Google에서 수정 한 이전 버전입니다. 따라서 더 이상 가능한 방법은 아닙니다.
그중 하나가 Function.prototype.call
Chrome은 다음 call
과 InjectedScriptHost
같이 eval 함수를 사용 하여 입력 한 표현식을 평가합니다.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
입니다.