Rails AJAX Response Refuses to Execute

May 28, 2009 06:17PM

check your response headers

I ran into an interesting problem today, all of my RJS calls refused to execute! Of course, In the end, it was entirely my fault. I had completed the AJAX DOM manipulation code, tested it for any mistakes, and had forgotten about it while I attended to other parts of the application.

When deploying for some internal testing, I noticed that the DOM wasn't updating. Very strange, especially since there were no errors reported.

  1. Firebug reported that my request had completed.
  2. A `puts "test"` verfied that code was executed before, and after the offending RJS file.
  3. Everything was OK with the response.

    try { alert("the response seems to be evaled fine!"); } catch (e) { alert('RJS error:\n\n' + e.toString()); alert('alert(\"the response seems to be evaled fine!\");'); throw e }

I was stumped, and thus began the arduous process of determining what I had done. After some code tracing, I stumbled upon this block in prototype.js:

respondToReadyState: function(readyState) { var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); if (state == 'Complete') { try { this._complete = true; (this.options['on' + response.status] || this.options['on' + (this.success() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(response, response.headerJSON); } catch (e) { this.dispatchException(e); } var contentType = response.getHeader('Content-type'); if (this.options.evalJS == 'force' || (this.options.evalJS && this.isSameOrigin() && contentType && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) { this.evalResponse(); } }

The console reported code executing before, and after this.evalResponse, but not inbetween! What had I done to break things? It all came down to my response headers.

The data for this project was migrated from a legacy MS Access program, so all data was in the Western ISO-8859-1 character set. Instead of fixing the data, I lazily forced all headers to "text/html; charset=ISO-8859-1".

This had the side effect of also forcing my RJS response headers to "text/html; charset=ISO-8859-1", while prototype is expecting "text/javascript;".

-Butch