Jul 21, 2014

Ajax request fails with 404 Not Found

When I started to convert a jQuery Ajax call that is used in the Drupal 7 Optimizely module, I found that it did not work in my local server environment, which consists of Apache 2.2 under Windows 7. The call was failing with a 404 Not Found error.

Using the Firebug extension for Firefox, I was able to see that the url for the Ajax request was missing the site root portion of the path. Specifically, the correct url is http://localhost/opti/ajax/optimizely where opti is the site root, but what was requested was http://localhost/ajax/optimizely . On this local system I have a number of different sites in subdirectories under the web server root.

I poked around in Apache to no avail, adding a RewriteBase directive in the site's .htaccess file.

I edited Drupal's settings.php to assign a value to $base_url, also with no effect.

Eventually, I stumbled on a casual side comment in the article cited below. It sounded like the same problem I was having, and it suggested the prepending of Drupal.settings.basePath in the url.

That solved the problem, as in the second line of code below.

  'url': Drupal.settings.basePath + 'ajax/optimizely',
  'type': 'POST',
  'dataType': 'json',
  'data': post,

  // Other code ...

where the original line was,

  'url': '/ajax/optimizely',

I confirmed this issue and this particular fix on a fresh installation of Drupal 7.29 and the Optimizely module 2.14.

However, the original javascript code has been working elsewhere. I was concerned that this change would break the functionality in other server environments. So I tested on a Linux Mint 16 system with Apache 2.4. The ajax call also works there, which gives me some confidence that the fix is broadly usable without introducing a regression.

N.B. Drupal.settings.basePath provides a path that has a trailing slash character. There was one place in the code where it was necessary not to have a beginning slash in the string literal 'ajax/optimizely' even though the resulting doubled slash worked fine in other cases.

N.B. For this ajax call to work with Apache, the mod_rewrite module must be enabled. I had to manually do this since the module was not enabled by default when I installed Apache 2.4.


Ajax in Drupal using jQuery


  1. For what it's worth your change continues to work on my OSX / MAMP setup.

    1. That's good to know.

      I submitted a patch on the D.O. optimizely page.

  2. Also note that the use of clean_urls has been the default for Drupal installs as far back as v5: https://www.drupal.org/getting-started/clean-urls

    1. Yes, it would be an uncommon scenario for clean urls, and therefore Apache's mod_rewrite, not to be enabled. Still, it's a possible corner case. I'd prefer that the dependency be mentioned.