Monday, October 20, 2014

jQuery event handlers and Content-Security-Policy

I wrote a while back about the efficiency angle of using .on() to set up event handlers, but I recently discovered a surprising additional feature: when an AJAX request to the server returns HTML, jQuery (or bootstrap?) carefully lifts out the embedded <script> elements, and runs their content via eval().  This doesn't work with a Content-Security-Policy in place, because eval is forbidden.

In my case, the script just wanted to bind a handler to all the newly-added elements that were also provided in the response.

Switching to binding the handler to the modal itself and filtering the interesting children meant that not only did I get the memory and CPU improvements of binding a single handler one time, but it eliminated the script—and the need to eval it—from the response.

Before, event handlers were bound with this code in the response, via jQuery secretly calling eval():
<script type="text/javascript">
$('#clientlist a').click(activateClient);
</script>

Afterwards, the response contained no script, and the event handlers were bound natively in my page initialization code:
$('#clientmodal').on('click', '#clientlist a', activateClient);

The content of #clientmodal was replaced whenever the modal was opened, but the modal itself (and its event handler) remained in place.

No comments: