views:

50

answers:

2

I'll try and explain the best I can...

I have a page, we'll call it pageA. When a button is clicked on that page, an ajax request is sent out and the return data is eval()'d. That data obviously contains javascript code. This code could possibly contain event listeners that are added to pageA when it is eval'd. Something like jquery $('body').click() for example.

When the button on pageA is clicked again, is there a function or something to remove any and all event listeners and data added on that eval.

I am capturing all the data returned from the ajax call into a variable before I eval the data, so is there a way to just do $(data).remove() and have all the event listeners and data magically disappear?

With eval data, it's not really added to the page per se where I could just do a text remove on the page and have all my problems go away, but the event listeners certainly do stay around.

Any ideas?

A: 

It may be easier to just copy all the currently attached event handlers on the particular button before you eval the javascript that's returned. Then unbind all the events (to which eval could have added extra handlers) and re-bind what was there before.

EDIT: Looks like someone's already had a similar question: jQuery: Unbind event handlers to bind them again later (though that uses jQuery).

I can't help but ask though, don't you have control over the JS that gets returned? Because if you do, it would be better to make sure malicious content is never sent in the first place.

R0MANARMY
+4  A: 

I will forgo the lecture on the evils of eval and recommend that you try namespacing your events in jQuery.

http://docs.jquery.com/Namespaced_Events

For example, have can the code in data add all new events with a namespace:

$(node).bind("click.myNameSpace", fn);

And when you want to remove it, you just do $(node).unbind("click.myNameSpace"), of course, that's assuming you know what elements they were added to. If you don't know the type of event that was added you can also do $(node).unbind(".myNameSpace") and it will remove all events under your namespace.

CD Sanchez
If you know of a better way, I would be more than happy to hear it. I have tried appending the script to the head, but the script tags never work, I don't particularly like eval myself....so, any suggestions would be heard.
Senica Gonzalez
@Senica Appending a script wouldn't be that much better than eval. They're both slower and exploitable. The idea is to try to send data instead of executable code.
CD Sanchez
Right, that unfortunately doesn't work in my case. This is for an admin and plugins. The plugins code is what is being eval'd. I don't want to restrict what can be done via the plugin, I just need to be able to remove it at some point.
Senica Gonzalez
@Senica I think event namespacing would be the way to go then -- if you can force yourself or whoever's authoring the plugin to follow the pattern. Adding events: $(node).bind("eventtype.pluginname", fn). Removing all events: $(body).children().unbind(".pluginname"). That may or may not work (it may also be a bit slow, but I'm assuming it won't be happening very frequently), my jQuery is a bit rusty, but you get the idea.
CD Sanchez