An abnormally terminating HTTP request

The other day I mentioned that I rarely encountered the "Worked fine in dev" problem. That's not quite true. I just spent about an hour trying to fix an issue with a Drupal 7 site. Everything worked on my localhost, which runs the latest Fedora. However, on my Centos 7 VPS I kept running into this error:

An AJAX HTTP request terminated abnormally.
Debugging information follows.
Path: /system/ajax
StatusText: n/a
ResponseText:
ReadyState: ,
    

The error happened when trying to upload an asset, such as an image, or when trying to edit product variations (the site uses Drupal Commerce). The issue had been happening ever since I moved the site to my VPS. I had tried to fix it a few times but never got very far. My workaround had been to just make any edits locally and to then upload everything. Clearly, that's not a very satisfactory solution.

So, what was the fix?

I could see in Firefox's Developer Tools that the response headers included x-frame-options: DENY, and the Console tab clearly showed there was a deny when AJAX was trying to perform its magic. The error was puzzling though, as nothing was downloaded from an external domain. I guess AJAX uses an object element or something. I'm really not sure; AJAX is a complete mystery to me and I avoid it if at all possible.

In any case, the first thing I tried was adding this to the site's settings.php file:

$conf['x_frame_options'] = 'SAMEORIGIN';
    

That didn't do the trick. I could still see the x-frame-options DENY header. I then decided to hunt down any relevant httpd configuration options:

# grep -ri "x-frame-options" /etc/httpd/
/etc/httpd/conf.d/ssl.conf:Header always set X-Frame-Options DENY
    

So that was the issue all along… changing the line to Header always set X-Frame-Options SAMEORIGIN and restarting httpd fixed the issue.

Post-mortem

Looking back the issue was quite easy to spot and fix. The reason it took me so long is that I kept going down the wrong rabbit hole. I first assumed it had something to do with the jQuery version, SELinux or perhaps something in the settings.php file. The mistake I made was to assume stuff and to then randomly try things to fix the issue. Online searches can actually be very unhelpful in this regard – something that looks relevant might be completely unrelated.

I also never let the first line of the error message sink in:

An AJAX HTTP request terminated abnormally.
    

In retrospect, that was pretty obvious. But that's the thing with retrospection… with hindsight lots of things are pretty obvious. The art is to not pass through the present with our eyes blindfolded.