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:
I wrote a simple workaround, please check my answer and let me know if you have a cleaner solution.
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.
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.
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.
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.
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);
Instead of deletion, I disabled the empty file inputs from the formData before class creation:
if(!file.val()){
file.attr('disabled', true);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With