モバイルSafari 8.0でサーバーにファイルをアップロードできません

悲しいけれど本当。 iOSの新しいバージョンには、ブラウザーからサーバーにファイルを送信できないようにするバグが含まれています。 HTMLページの任意のフォームでファイルを選択して送信しようとすると、ブラウザーはファイルなしでリクエストを送信します。 リクエストに対する応答を待っていることを示していますが、実際には答えは返されません。



さらに、バグはHTMLフォームだけではありません。 FormData



オブジェクト(XMLHttpRequest Level 2 APIの一部)を作成してJavascriptからファイルを送信すると、同じ結果が生成されます。 また、HTMLブラウザー(Apache Cordovaなど)のラッパーであるネイティブアプリケーションから同じことを行っても、同じ結果が得られます。



なぜ答えが来ないのですか。 ファイルが単に送信されなかった場合、空のファイルがサーバーに届くか、サーバーがフォームをファイルなしで送信したというエラーを返すと予想できます。 ただし、サーバーは単に応答を送信せず(400の不正な要求であっても)、接続を閉じません。 問題は、正確にどのリクエストが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バイトを送信するのを待ち、ブラウザーはすでにリクエスト全体を送信したと判断し、サーバーからの応答を待っています。 これらはいずれも発生せず、接続はタイムアウトによって単純に閉じられます。



このバグは、iOS 8.0(ビルド12A365)のSafari 8.0(ビルド600.1.4)に表示されます。 興味深いことに、XcodeにバンドルされているiOSシミュレーターでは、ビルド番号は同じですが、このバグは表示されません。 ただし、実際のデバイス(iPhone 4S、iPhone 5、iPad 3がテスト済み)では、バグは常に発生します。 バグが次のマイナーアップデートで修正されることを願っています。



誰かが自分でエラーを確認したい場合、または他のデバイスを試したい場合。



Safariのデバッガーはここでは役に立ちません。なぜなら、いずれの場合でも、ファイルのコンテンツなしで要求本文を表示するからです。 なぜなら HTTPを直接操作する際にエラーが発生し、オンラインの例を作成するのは非常に困難です。 netcatを起動してリクエストを送信するよりも賢い方法は思いつきません。 手順は次のとおりです。



1)デバイスと同じwi-fiネットワーク内のコンピューターでnetcat -l 8000



を実行します。

2) jsbinまたは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>
      
      





192.168.5.59は、netcatが実行されているコンピューターのIPアドレスです。



3)デバイスのビンまたはフィドルを開きます。 任意のファイルを選択して送信します。

4)netcatの出力を見てください。



回答が記事の回答と似ている場合は、バグが存在します。 ファイルの内容が最終行の前にある場合、いいえ。



All Articles