Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My $.ajax request stopped working properly on iOS 11.3

Tags:

ajax

ios

This code used to work just fine and fast for years.

Given that $.ajax does not receive any file data, as of update to iOS 11.3 this $.ajax seems to work very slowly up to 20 seconds to submit a simple text-only form when tested on iOS browser.

But if the file element passes file data, the $.ajax works just fine in both cases and just as fast as expected.

HTML ---
<form enctype="multipart/form-data" id="chatform" method="post">
    <input type="file" name="pic" id="pic" class="hidden" />
    <textarea name="chattextarea" id="chattextarea" rows="3" cols="10"></textarea>
    <input type="button" value="Send" onclick="sendMessage();" />
</form>

JavaScript ---
function sendMessage() {
    var formData = new FormData($("#chatform")[0]);
    $.ajax({
        url: 'send.php',
        type: 'POST',
        data: formData,
        async: true,
        cache: false,
        contentType: false,
        processData: false,
        success: function (returndata) {
            /* some success message */
        }
    });
}

Is this an iOS 11.3 bug?

----- EDIT -----

Yes indeed it is not only iOS 11.3 bug, but also a Safari 11.1 bug. So far I tested these environments and replicated the bug:

  1. Mac OS, Safari
  2. iOS, Safari
  3. iOS, Chrome
  4. iOS, WKWebView (hybrid app)

I wrote a simple workaround, please check my answer and let me know if you have a cleaner solution.

like image 775
John Doe Avatar asked Mar 30 '18 17:03

John Doe


People also ask

How do I report a problem with an account in Ajax?

Open the Ajax app and click on the menu icon in the upper left corner of the screen. Select Account. Then click Edit Account. Click on the menu icon in the upper left corner of the screen. Select Report a problem. In the Ajax PRO app, the menu button is available only on the screen with the list of hubs linked to an account.

Where do Ajax requests come from?

Because an Ajax request originates in the client’s browser, it must reference a file at another location but on the same domain as the source of the request. Your server, however, unlike the client’s browser, is not limited in this way.

Is Ajax a security risk to the user?

This doesn’t present any security risk to the user because the requests to the third-party service are made on your server. So, once the information has been obtained at the server level, the next step in the Ajax call is to send a response back to the client, which in this case would include the data obtained from the third-party web service.

Does the “success” box indicate a completed Ajax request?

Although this particular indicator does not point out a completed Ajax request, the principle is the same: the “Success” box appears after the page that submits the form has finished loading, and the box is colorful and distinct. A similar graphic or indicator could be used at the end of an Ajax request to tell users that content has been updated.


2 Answers

This function works on iOS 11.3, iOS 10.2 and windows Chrome 65.0.3325.181. Can someone help to test on other browsers?

function formDataFileFix(formData) {
    try {
        if (formData.keys) {
            var formKeysToBeRemoved = [];
            for (var key of formData.keys()) {
                var fileName = null || formData.get(key)['name'];
                var fileSize = null || formData.get(key)['size'];
                if (fileName != null && fileSize != null && fileName == '' && fileSize == 0) {
                    formKeysToBeRemoved.push(key);
                }
            }
            for (var i = 0; i < formKeysToBeRemoved.length; i++) {
                formData.delete(formKeysToBeRemoved[i]);
            }
        }
    }
    catch(err) {
        console.log(err.message);
    }
}

var formData = new FormData($(formID)[0]);
formDataFileFix(formData);
like image 122
Peter Avatar answered Oct 22 '22 02:10

Peter


Instead of deletion, I disabled the empty file inputs from the formData before class creation:

if(!file.val()){
   file.attr('disabled', true);
}
like image 23
LonlyLockley Avatar answered Oct 22 '22 02:10

LonlyLockley