[Перевод] Вы не можете закачать файлы на сервер в мобильном Safari 8.0
Печально, но факт. Новая версия iOS содержит баг, который делает невозможным отправку любых файлов на сервер из браузера. Когда вы выбираете файл в любой форме на HTML странице и пытатесь его отправить, браузер посылает запрос без файла. Он показывает, что ждет ответа на запрос, но на самом деле ответ не приходит.Более того, баг касается не толко HTML-форм. Если вы отправляете файл из Javascript, конструируя объект FormData (часть API XMLHttpRequest Level 2), это приводит к тому же результату. И даже если вы делаете то же самое из нативного приложения, которое является оберткой над HTML-барузером (например, Apache Cordova), то получаете такой же результат.
Почему же не приходит ответ? Если бы файл просто не отсылался, мы могли бы ожидать, что на сервер приходил бы пустой файл или сервер возвращал бы ошибку, что форма отправлена без файла. Однако сервер просто не шлет никакого ответа (даже 400 bad request) и не закрывает соединение. Все дело в том, какой именно запрос шлет 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-- Из заголовков видно, что запрос с отправкой файла должен иметь длину 134573 байта (заголовок Content-Length), а на самом деле в теле запроса отсутствует тело файла, из-за чего реальная длина запроса составляет 176 байт. В результате сервер ждет, когда браузер пошлет недостающие 134397 байт, а браузер думает, что он послал уже весь запрос и ждет ответа от сервера. Ни того ни другого не произойдет никогда и соединение просто закрывается по таймауту.Баг проявляется в Safari 8.0 (билд 600.1.4) под iOS 8.0 (билд 12A365). Что интересно, под симулятором iOS, который идет в комплекте с XCode, данный баг не проявляется, хотя номера билдов там такие же. Однако на реальных устройствах (были проверены iPhone 4S, iPhone 5, iPad 3) баг воспроизводится всегда. Мы надеемся, что баг будет исправлен уже в ближайшем минорном обновлении.