"Decompile" Javascript function?
[1] Ok, I don't even know how to call this, to be honest. So let me get some semi-pseudo code, to show what I'm trying to do. I'm using jQuery to get an already existing script declared inside the page, inside a createDocument()
element, from an AJAX call.
GM_xmlhttprequest({ ... load:function(r){ var doc = document_from_string(r.responseText); script_content = $('body script:regex(html, local_xw_sig)', doc).html(); var scriptEl = document.createElement('script'开发者_开发知识库); scriptEl.type = 'text/javascript'; scriptEl.innerHTML = script_content; // good till here (function(sc){ eval(sc.innerHTML); // not exactly like this, but you get the idea, errors alert('wont get here ' + local_xw_sig); // local_xw_sig is a global "var" inside the source })(scriptEl); } });
So far so good, the script indeed contains the source from the entire script block. Now, inside this "script_content", there are auto executing functions, like $(document).ready(function(){...}) that, everything I "eval" the innerHTML, it executes this code, halting my encapsulated script. Like variables that doesn't exist, etc.
Removing certain parts of the script using regex isn't really an option... what I really wanted is to "walk" inside the function. like do a (completely fictional):
script = eval("function(){" + script_content + "};"); alert(script['local_xw_sig']); // a03ucc34095cw3495
Is there any way to 'disassemble' the function, and be able to reach the "var"s inside of it? like this function:
function hello(){ var message = "hello"; } alert(hello.message); // message = var inside the function
Is it possible at all? Or I will have to hack my way using regex? ;P
[2] also, is there any way I can access javascript inside a document created with "createDocument"?
Simply trying to access a local variable inside a function from outside of it is impossible due to scope. However, using closures you can absolutely accomplish this:
function hello(msg){
return function message(){
return msg;
}
}
alert(hello("yourMessage")()); // will alert "yourMessage"
Note exactly what's happening here. You are calling a function which returns a function, in which "yourMessage"
is now defined inside its scope. Calling that inner closure the second time will yield that variable you set earlier.
If you are not familiar with closures in JS, I suggest you read this wonderful FAQ.
It's not possible that way. You can introspect object's properties (any function is an object), but not before you have created an instance with new
operator.
Looking at your code sample, it seems that your approach is a bit messy – eval()'ing script blocks is something one should not do unless absolutely necessary (a situation I can't imagine).
In your example at
function hello(){
var message = "hello";
}
alert(hello.message); // message = var inside the function
you can in fact use hello.toString() to get the function source, like this:
alert(hello.toString().match(/var message = \"(.*)\";/));
You want to eval the script in global scope. Briefly it is,
// Evalulates a script in a global context
globalEval: function( data ) {
data = jQuery.trim( data );
if ( data ) {
if ( window.execScript )
window.execScript( data );
else if ( jQuery.browser.safari )
// safari doesn't provide a synchronous global eval
window.setTimeout( data, 0 );
else
eval.call( window, data );
}
}
Also check out Google's caja for secure external script evaluation.
精彩评论