Search
Close this search box.

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);
          }
          });

Print | posted on Tuesday, June 26, 2018 6:34 PM | Filed Under [ iossafaripostjQuery ]

This article is part of the GWB Archives. Original Author: Eric Newton

Related Posts