Ajax Post on iOS Safari not working? Its the cache!

Not sure when this took effect, but a simple public facing web application we wrote using jQuery.ajax for doing our form posts nicely started not working on iOS devices.  The reports came in occasionally, but not with any fervor, so we chalked it up to user error.  

However, one day after the 10th report came in, I decided to check on my iPad Air, and… hmmm “Server didn’t respond within the timeout”.  I don’t have a Mac so debugging Safari directly on iOS is virtually impossible for me, (Thanks Apple! Really!).  So I fired up Chrome on my Windows PC and the server responds just fine.  Sub 100ms responses for the exact same conditions.

I try other devices, other browsers, works just fine… can’t test Safari on Windows though because Apple took their ball and went home.  (Boo hoo Apple)

So I finally borrow a friend’s Mac and iPad for a few hours, and find out that iOS Safari just isnt even making the request… what the???

Looking at the jQuery ajax call we have something like this:

var formData;
formData = new FormData(form);
          $.ajax({
            url: $(form).attr("action"),
            type: "POST",
            data: formData,
            processData: false,
            contentType: false,
            timeout: 15000,
            success: function() {
              $(".content-form__cta-item").find("a").trigger("click");
              $(".form-validation-modal").remove();
              return $("body").append(_self.openModelTemplate);
          }
          , error : function(jqXHR, textStatus, errorThrown) {
            console.log("error. textStatus: %s  errorThrown: %s", textStatus,
                        errorThrown);
            return alert(
                "There was an error handling your request please try again.");
          }
          , complete : function(jqXHR, textStatus) {
            return console.log("complete. textStatus: %s", textStatus);
          }
          });

I searched a little and there was mention of Safari’s XmlHttpRequest shutting down any synchronous activities, so I added “async: true”   No dice.  

Went back to searching, and finally found something relevant, a fellow having the same problem, but the year is 2014 for the fix… I try anyways, and add “cache: false”

Turns out, iOS Safari will cache the post request, but will sit waiting for a response from a non-connection!  Um, wtf?

Searched some more, and finally found something that works:  setting the header Cache-Control to no-cache via headers: { “cache-control”: “no-cache” } ends up telling the brain dead Safari XmlHttpRequest implementation to always hit the base server to get a response for the POST.

Here’s the final code, working:

var formData;
formData = new FormData(form);
          $.ajax({
            url: $(form).attr("action"),
            type: "POST",
            data: formData,
            cache: false,
            processData: false,
            contentType: false,
            timeout: 15000,
            async: true,
            headers: {
              "cache-control": "no-cache"
            },
            success: function() {
              $(".content-form__cta-item").find("a").trigger("click");
              $(".form-validation-modal").remove();
              return $("body").append(_self.openModelTemplate);
          }
          , error : function(jqXHR, textStatus, errorThrown) {
            console.log("error. textStatus: %s  errorThrown: %s", textStatus,
                        errorThrown);
            return alert(
                "There was an error handling your request please try again.");
          }
          , complete : function(jqXHR, textStatus) {
            return console.log("complete. textStatus: %s", textStatus);
          }
          });
This article is part of the GWB Archives. Original Author: gwbarchive

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.