web-dev-qa-db-ja.com

最新のブラウザでファイルをアップロードする最良の方法は何ですか

(単一の)ファイルをサーバーにアップロードし、アップロードの進行状況を表示したい。

HTTP POSTを使用してファイルをアップロードできることを知っています。私はWebソケットに精通していませんが、理解しているように、バイナリデータもそのように送信できます。Webソケットは双方向なので、アップロードの進行状況を取得できます。

古いブラウザについては心配していませんので、iframeとFlashソリューションは、そのルートを進める上で大きな利点がない限り、あまり魅力的ではありません。

また、最高のサーバー側テクノロジーについても興味があります。 DjangoのようなWSGIサーバーを使用する利点はありますか?または、Node.jsのようなノンブロッキングI/Oテクノロジーでしょうか?私は、WebフレームワークxがWebフレームワークyより優れているか、サーバーxがサーバーyより優れているかを尋ねていません。しかし、単にクライアントにアップロードを提供するために理想的なテクノロジーが持つべきものです。

更新サーバー側は、アップロードを容易にするためにクライアントで利用可能なテクノロジー/ APIに関係がないようです。

62
Tom

Edit(2017-10-17):現在、 Fetch API を使用するオプションもあります。より現代的な約束ベースのAPIの背後にあるXMLHttpRequestと本質的に同じ機能を提供します。ネイティブでwindow.fetch()をサポートしていないブラウザには、 polyfill があります(これは現在、主にInternet Explorerと古いSafariバージョンです)。

XMLHttpRequest vs. Webソケットvs.その他

明らかに XMLHttpRequest 。最新のブラウザでのその機能は膨大であり、ほぼすべてのシナリオをカバーしています。標準のPOSTまたはPUTリクエストを生成します。Webサーバーとフレームワークの組み合わせはそれを処理できます。

Webソケットはいくつかのシナリオには適していますが、多くの複雑さを追加する別のプロトコルです-サーバーからのリアルタイムの応答が必要な場合にのみ使用する価値があります。そして、あなたが自分自身に気づいたように、Flashのような他のアプローチは単にmerelyいハックです。

バイナリデータの送信

通常、ファイルに直接アクセスすることはできません。したがって、ページのどこかに_<input type="file">_フォームフィールドがあり、ユーザーがファイルを選択するのを待ちます。オプションは次のとおりです。

  • ファイルの内容のみを送信する:request.send(input.files[0])。リクエストの本文はファイルのコンテンツであり、他には何もありません。エンコードは実行されず、ファイル名などのメタデータは送信されません。 ブラウザの互換性 :Chrome 7、Firefox 3.6、Opera 12、IE 10。
  • フォーム全体のデータを送信するrequest.send(new FormData(input.form))。ここでは、フォームの内容は_multipart/form-data_としてエンコードされます。つまり、複数のフォームフィールドを送信でき、フィールド名やファイル名などのメタデータも送信されます。また、送信前に FormDataオブジェクトを変更 することもできます。サーバー側のフレームワークによっては、このリクエストの処理は生データよりも簡単な場合があります。通常、使用できるヘルパーは多数あります。 ブラウザの互換性 :Chrome 6、Firefox 4 Opera 12、IE 10。
  • 型付き配列の送信 :ファイルがなくても、その場で生成したバイナリデータを送信したい場合に備えて。ここでは追加のエンコードは実行されません。したがって、サーバー側に関する限り、これはファイルコンテンツの送信のように機能します。 ブラウザの互換性 :Chrome 9、Firefox 9 Opera 11.60、IE 10。

アップロードの進行状況を表示する

_XMLHttpRequest.upload_のprogressイベントを聴くことができますprogressイベント にはloadedおよびtotalプロパティがあり、リクエストでどれだけの距離があるかを判断できます。 ブラウザの互換性 :Chrome 7、Firefox 3.5、Opera 11.60、IE 10。

JavaScriptライブラリ

もちろん、ここで説明する機能をラップする既存のライブラリがあります。これらは他の回答で言及されていますが、ウェブでの検索は確かにさらに多くの結果をもたらします。ここで明示的にライブラリを提案したくはありません-使用する必要があるライブラリは、純粋に好みの問題です。

60
Wladimir Palant

私の答えはかなり遅いですが、ここにそれが行きます:


短い答え:

XMLHttpRequestは、最新のブラウザーでファイルをアップロードする最良の方法です。



XMLHttpRequestとは

XMLHttpRequestは、Microsoftによって設計され、Mozilla、Apple、およびGoogleに採用された JavaScript オブジェクトです。現在、W3Cで 標準化されています 。ページ全体を更新する必要なく、URLからデータを取得する簡単な方法を提供します。 Webページは、ユーザーの操作を中断することなく、ページの一部のみを更新できます。 XMLHttpRequestは [〜#〜] ajax [〜#〜] プログラミングで頻繁に使用されます。

その名前にもかかわらず、XMLHttpRequestはXMLだけでなく、あらゆるタイプのデータの取得に使用でき、 [〜#〜] http [〜#〜]以外のプロトコルをサポートします。file and ftpを含む)。

XMLHttpRequestオブジェクトは、Html5仕様で改築されました。具体的には、 XMLHttpRequest Level 2


利点:

  • FileBlob、およびFormDataなどのアップロードおよびダウンロード用のオブジェクトのバイトストリームの処理
  • 進行イベントアップロードおよびダウンロード中
  • Cross-Originリクエスト
  • 匿名リクエスト-HTTPリファラーを送信しないことを許可します
  • リクエストにTimeoutを設定する機能
  • アップロードはbackgroundで行われています
  • ユーザーがいるページはそのまま残ります
  • サーバー側に変更を加える必要はありません。したがって、既存のサーバー側のロジックは変更しないままにしておく必要があります。

Html5進捗イベント:

Html5 Progress Events仕様 に従って、Html5 progressイベントは、とりわけ以下の情報を提供します:

total - Total bytes being transferred
loaded - Bytes uploaded thus far
lengthComputable - Specifies if the total size of the data/file being uploaded is known 

上記の情報を使用すると、「残り時間」情報をユーザーに提供するのは非常に簡単です。


ユーザーに通知し続ける:

ユーザーが利用できるファイルに関する情報:

  1. ファイル名
  2. ファイルサイズ
  3. MIMEタイプ
  4. 完了率の進行状況バー
  5. アップロード速度またはアップロード帯域幅
  6. おおよその残り時間
  7. これまでにアップロードされたバイト
  8. サーバー側からの応答

XMLHttpRequestデモを使用したファイルのアップロード

例については、「 Html5を使用した進行状況表示demo を使用したファイルのアップロード」を確認してください。必要なJavaScriptコードはすべてページにありますが、CSSは含まれていません。セキュリティ上の理由から、ファイルタイプはjpg、png、gif、およびtxtに制限されています。最大ファイルサイズは2MBです。


XMLHttpRequestブラウザーの互換性:

XMLHttpRequest Browser compatibility


19
Pedro Lobito

おそらく、JavascriptのファイルAPIは、最新のブラウザーでの最良の方法です。

http://robertnyman.com/2010/12/16/utilizing-the-html5-file-api-to-choose-upload-preview-and-see-progress-for-multiple-files/ =

http://www.sitepoint.com/html5-javascript-file-upload-progress-bar/

サーバー側では...メインフレームワークのいずれにも、HTTPファイルPOST機能が十分にカバーされています。

5
vtortola

個人的には、blueimp jQuery File Upload Pluginが好きです( https://blueimp.github.io/jQuery-File-Upload/

複数のファイル選択、ドラッグアンドドロップのサポート、進行状況バー、検証およびプレビュー画像、jQueryのオーディオとビデオを備えたファイルアップロードウィジェット。クロスドメイン、チャンク、再開可能なファイルのアップロードとクライアント側の画像サイズ変更をサポートします。標準のHTMLフォームファイルのアップロードをサポートする任意のサーバー側プラットフォーム(PHP、Python、Ruby on Rails、Java、Node.js、Goなど)で動作します。

デモ:

ダウンロード(GitHub):https://github.com/blueimp/jQuery-File-Upload

4
ptCoder

ファイルはAJAX経由でアップロードできます。

jQueryフォームプラグイン を使用します。ファイルをフォームにバインドし、シリアル化するという汚い作業をすべて行います。また、アップロードの進行状況を表示することもできます。

サーバースタックはそれとはあまり関係ありません。

デモ

4
xyres