Jordan Soltman
Jordan Soltman

Reputation: 3893

Existing async requests failing with network error when file/image picker opened on iOS Safari

I have a project where I need to upload multiple images asynchronously. It was working great everywhere (Chrome, Firefox, MacOS Safari, Android Chrome, iOS Safari on an iOS simulator running 11.4). However, on my iPhone using iOS Safari (and a few other iPhones I tried all running 11.4) the existing requests were failing when I opened the image/file picker.

I've since distilled the problem down to some much more simple code:

<html>
  <head>
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
    <script src="/javascripts/main.js"></script>
  </head>
  <body>
    <p>Upload Progress: <span id="status">Not Started</span></p>
    <p>Blob Upload: <button id="blobUpload">Upload Blob</button></p>
    <p>File Input: <input type="file" /></p>
  </body>
</html>

This is main.js:

$(document).ready(() => {
  $("#blobUpload").click(() => {

    const status = document.getElementById("status");
    status.innerHTML = "Started";

    // Create an array about 2mb in size (similar to an image);
    // and append it to a form data object
    const intArray = new Uint8Array(2000000);
    const blob = new Blob([intArray]);
    const formData = new FormData();
    formData.append('file', blob);

    const request = new XMLHttpRequest();

    request.upload.addEventListener('progress', (ev) => {
      const percent = Math.round(ev.loaded / ev.total * 100);
      status.innerHTML = percent + '%';
    }, false);

    request.upload.addEventListener('error', (ev) => {
      status.innerHTML = '<span style="color: red">Network Error</span>';
    });

    request.open('POST', '/upload', true);
    request.send(formData);
  });
});

If I click the 'Upload Blob' button and then don't do anything else, it works 100% of the time, never ever fails. However, if I click the upload blob button, then while it's uploading I click a file input (which is totally unrelated to everything else), choose one of the menu options (Take Photo or Video, Photo Library, or Browse), then either choose something, or take a photo, or even just hit cancel to go back, the uploading blob will fail about 1/3 of the time with a 'Failed to load resource: The network connection was lost.' error. It doesn't matter what is being uploaded, (image or blob or whatever).

Here is a video showing what happens.

It's been 2 days of debugging this, and I've found NOTHING of interest in my research and believe me I've tried. Any help would be appreciated. Beginning to believe it may just be a bug with Safari.

Upvotes: 5

Views: 1818

Answers (3)

Jordan Soltman
Jordan Soltman

Reputation: 3893

It appears that this was a problem with Safari going into the background when the photo picker came up, and as a background app, existing network requests would often not complete. No easy work around for that. I've been testing iOS 13 and as far as I can tell this is fixed. Interested to see if anyone else with this problem can also verify, but I've been running tests on iOS 12 vs iOS 13 and it's consistently failing with 12 and succeeding with 13.

Upvotes: 2

miknik
miknik

Reputation: 5951

When you launch the file picker etc and make it fail are you getting an empty file field in your form?

There's a known bug within Safari which will cause XMLHttpRequest uploads to fail if a form has an empty file field.

Upvotes: 0

Bharath Sampath Kumar
Bharath Sampath Kumar

Reputation: 22

The answer here could lie with not fixing the error, but with better UI/UX.

While the file is uploading, you can disable the file picker button. You can have also have a cancel button beside the (disabled) file picker button that shows up while something is uploading, just in case the user decides to cancel the upload.

And if you need to upload multiple files, let it all be stacked up and you can run a single upload that sequentially uploads all the files.

Upvotes: -1

Related Questions