📜 ⬆️ ⬇️

You cannot upload files to the server in mobile Safari 8.0

Sad but true. The new version of iOS contains a bug that makes it impossible to send any files to the server from the browser. When you select a file in any form on the HTML page and try to send it, the browser sends a request without a file. It shows that it is waiting for a response to the request, but in fact the answer does not come.

Moreover, the bug concerns not only HTML forms. If you send a file from Javascript by constructing a FormData object (part of the XMLHttpRequest Level 2 API), this results in the same result. And even if you do the same from a native application that wraps an HTML browser (for example, Apache Cordova), you get the same result.

Why the answer does not come. If the file was simply not sent, we might expect that an empty file would come to the server or the server would return an error that the form was submitted without a file. However, the server simply does not send any response (even 400 bad request) and does not close the connection. The thing is, what kind of request sends Safari.
')
 POST /form/ HTTP/1.1 Host: 192.168.5.59:8000 Referer: http://192.168.5.59:8000/ Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGVP84V9BXQSqpZw2 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Content-Length: 134573 Accept-Language: ru Origin: http://192.168.5.59:8000 Accept-Encoding: gzip, deflate Connection: keep-alive User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A365 Safari/600.1.4 ------WebKitFormBoundaryGVP84V9BXQSqpZw2 Content-Disposition: form-data; name="file"; filename="image.jpg" Content-Type: image/jpeg ------WebKitFormBoundaryGVP84V9BXQSqpZw2-- 

From the headers you can see that the request with the file sending should be 134573 bytes in length (Content-Length header), and in fact there is no file body in the request body, which is why the actual length of the request is 176 bytes. As a result, the server waits for the browser to send the missing 134397 bytes, and the browser thinks that it has already sent the entire request and is waiting for a response from the server. Neither one nor the other will ever happen and the connection is simply closed by timeout.

The bug manifests itself in Safari 8.0 (build 600.1.4) under iOS 8.0 (build 12A365). Interestingly, under the iOS simulator that comes with Xcode, this bug does not appear, although the build numbers are the same there. However, on real devices (iPhone 4S, iPhone 5, iPad 3 were checked), the bug is always played. We hope that the bug will be fixed in the next minor update.

If someone wants to see the error himself or try other devices.

The debugger in Safari is useless here, because in any case it shows the request body without the contents of the files. Since error directly in working with HTTP, making an online example is quite difficult. I did not think of anything smarter than running netcat and sending requests for it. Here is the instruction:

1) Run netcat -l 8000 on a computer in the same wi-fi grid with the device.
2) Make the simplest form on jsbin or jsfiddle :
 <form action="http://192.168.5.59:8000/form/" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit"> </form> 

Where 192.168.5.59 is the ip address of the computer where netcat is running.

3) Open the made bin or fiddle on the device. Choose any file, send.
4) Look at the output of netcat.

If the answer is similar to the one in the article, then the bug is present. If before the last line there is the contents of the file, then no.

Source: https://habr.com/ru/post/237455/


All Articles