この記事では主にBlodをベースにしたajaxプログレスバーダウンロード実装のサンプルコードを紹介していますが、編集者が非常に良いと思ったので、参考として共有させていただきます。編集者をフォローして見てみましょう
通常のブラウザのダウンロード
Web 開発では、ダウンロード機能を実装したい場合、新しい Web ページを使用するか、iframe を使用することがよくあります。実装は実際には非常に簡単です:
<a target="_blank" href="download.zip" rel="external nofollow" >点击下载</a> //或者 <iframe style="display:none" src="download.zip"></iframe>
ユーザーがタグをクリックして新しいタブをポップアップ表示した後、または iframe を開いた後、ブラウザーはダウンロード応答を受け入れ、添付ファイルをダウンロードします。実際、いわゆる添付ファイルのダウンロードとは、ブラウザが応答メッセージのヘッダーを読み取った後、ブラウザがダウンロード プロンプト ボックスを生成し、ユーザーが確認した後にファイルのダウンロードを続行することを意味します。ファイルは実際にはストリームであり、ブラウザはこの送信プロセスを自動的に管理し、進行状況バー、ダウンロードの停止ボタン、続行ボタン、ダウンロードの更新ボタン、ダウンロードされたバイト数の表示ボタンなどを自動的に生成します。等。これはブラウザが自動的に行いますが、プロセス全体は私たちの制御下にはありません。
ajax download
ブラウザによるダウンロードのサポートは、基本的にニーズを満たすことができます。一般的なシナリオでは、他のダウンロード方法を検討することはほとんど意味がありません。ただし、ブラウザーのダウンロードでは満たせないシナリオがまだいくつかあります。たとえば、Web アプリケーションでダウンロードの進行状況を監視したり、ダウンロードの完了後に特定のイベントをトリガーしたり、Web アプリケーションがダウンロード プロセスを自動的にキャンセルしたりする必要があります。ワーカーを使用して、ダウンロードなどを実行するバックグラウンドを作成します。上記の状況では、Blod オブジェクトに基づいた ajax ダウンロードを使用できます。
Ajax による添付ファイルのダウンロードは、Ajax による添付ファイルのアップロードと同じであり、ブラウザーは ajax2.0 をサポートする必要があります。実際、いわゆるダウンロードは通常の ajax リクエストと何ら変わりません。ただし、ダウンロードは通常バイナリ ファイルであり、テキスト オブジェクトや JavaScript がカプセル化できるタイプを提供する必要はありません。これは血液です。したがって、応答タイプと responseType の値を「blod」に設定します。
var xhr =new XMLHttpRequest(); xhr.open(option.type ? option.type.toUpperCase() : 'GET', url, true); xhr.responseType = 'blob';
では、XMLHttpRequest オブジェクトの responseType フィールドの値が blob である必要があります。では、血液オブジェクトとは何でしょうか?
blod オブジェクト
MDN では、次のように説明されています:
Blob オブジェクトは、読み取り専用の生データを含むファイルのようなオブジェクトです。 Blob オブジェクト内のデータは、JavaScript のネイティブ形式である必要はありません。ファイル インターフェイスは Blob に基づいており、Blob の機能を継承し、ユーザーのコンピューター上のローカル ファイルのサポートを拡張します。 Blob オブジェクトを通じて、バイナリ ストリームをオブジェクトにカプセル化できます。
HTML5 のファイル関連 API を知っている場合は、blod オブジェクトについてもよく知っているはずです。 BLOD はバイト ストリームをファイルにカプセル化できます。XMLHttpRequest オブジェクトの responseType 値が blob である場合、応答本文を blob オブジェクトとして扱うことができます。
xhr.onload = function () { //对于重定向的文件不予理会 if (this.status >= 200 && this.status < 300) { var blob = new Blob([this.response], {type: this.response.type}); } }
ajax を使用してファイルをダウンロードし、そのファイルを BLOB オブジェクトとして保存し、ブラウザーにキャッシュします。では、ユーザーがファイルをハード ドライブに保存できるようにするにはどうすればよいでしょうか?
BLOB オブジェクトをハードディスクに保存します
ブラウザのダウンロードを模倣し、タグまたは iframe を生成してから URL を生成することで、ブラウザに戻ってダウンロードできるようになります。添付ファイルウィンドウを保存するためのファイルを自動的に生成します。 URL は URL.createObjectURL(blob) メソッドを使用して取得できます。URL.createObjectURL は Blob オブジェクトと File オブジェクトをサポートし、現在のユーザーがこれらのオブジェクト (もちろんダウンロードを含む) にアクセスできるように仮想 URL を生成できます。サーバーから直接ダウンロードするのとは異なり、ここでのダウンロードはクライアントの内部で行われ、ネットワーク IO を使用しないため、ダウンロードはほぼ瞬時に行われます。ただし、URL を生成した後は解放する必要があります。そうしないと、BLOB リソースはガベージ コレクションされません。URL.revokeObjectURL を使用して URL を解放し、BLOB リソースを解放できます。 IE ブラウザーの場合、独自の Blob オブジェクト処理戦略のセットがあり、これは 2 つのナビゲーター メソッド (msSaveOrOpenBlob と msSaveBlob) です。
//ie的下载 if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, fileName); } else { //非ie的下载 var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = fileName; link.click(); window.URL.revokeObjectURL(link.href); }
プログレスバーとダウンロードキャンセル
実際には、XMLHttpRequestオブジェクトにはprogressイベントがありますが、結局のところ、一般的なリクエストは無視されます。瞬時に行われるため、進行状況バーを設定する必要はありません。ただし、ajax のダウンロードは異なります。添付ファイルのダウンロードには時間がかかるため、進行状況イベントをリッスンすることで、ダウンロードの進行状況を取得することができます。
ダウンロードをキャンセルするには、XMLHttpRequest オブジェクトの abort 関数を使用します。また、load イベントでダウンロードの完了を監視し、error イベントでダウンロードの失敗を監視できます。つまり、ajax ダウンロードと通常の ajax リクエストのイベントとメソッドはまったく同じです。
パフォーマンスの最適化と同一オリジンポリシー
Ajax ダウンロードは、長い接続と同様に、通常のリクエスト、特にダウンロードよりも多くの帯域幅を占有します。したがって、ダウンロード プロセス中に他の ajax リクエストがブロックされる可能性があるため、ajax によってダウンロードされたリソースとその他のリクエストされたリソースには異なるドメイン名を使用することが推奨されますが、これにより同一生成元ポリシーの問題という新たな問題が発生します。
同一生成元ポリシーはブラウザのセキュリティの基礎です。同一生成元ポリシーがなければ、どの Web サイトでも CSRF 攻撃を開始する可能性があります。ダウンロードされたリソースの URL が現在のページの URL と同じ生成元であることが保証できない場合、同一生成元ポリシーがトリガーされ、ダウンロードは失敗します。そのため、Ajax クロスドメイン処理が必要です。 iframe および新しいタブのダウンロード方法と比較すると (実際、iframe にも同一生成元ポリシーがあり、iframe 内のページと親ページが相互にコンテンツにアクセスできないようにする必要がありますが、ダウンロード機能にはこのようなものは含まれません)そのため、iframe のダウンロードは同一生成元ポリシーの影響を受けません)、ajax のダウンロードは本質的に ajax であるため、ブラウザーの同一生成元ポリシーの影響を受けます。したがって、オリジナル以外のソースから添付ファイルをダウンロードする場合、添付ファイルが配置されているサーバーは cors をサポートする必要があります。サーバーが Cookie にアクセスする必要がある場合は、XMLHttpRequest オブジェクトの withCredentials を true に設定する必要があります。
同時に、同一生成元ポリシーにより、通常のダウンロード サービスは cors 処理を行わないため、ajax を使用してサードパーティのリソースをダウンロードすることはできません。結局のところ、iframe のダウンロードや新しいタブのダウンロードは影響を受けません。同一生成元ポリシーの影響を受けるため、cors 処理を行う必要はありません。これにより、Ajax ダウンロードの適用可能性が大幅に制限されます。
概要:
最後に、ajax ダウンロードの使用シナリオをまとめます:
1. ユーザーのダウンロードの進行状況が遅すぎることがわかった場合など、ダウンロードの進行状況の監視が必要なシナリオであり、他の解決策を積極的に提供します。
2. ダウンロードの完了後に、デスクトップ通知ポップアップなどの特定のイベントをトリガーする必要があります。
3. バックグラウンドでのダウンロードが必要です。たとえば、ユーザーが Web ページを開いた後に添付ファイルをこっそりダウンロードしてキャッシュし、ユーザーが本当に添付ファイルをダウンロードしたいときにローカルに保存することができます。ワーカーを使用してバックグラウンド スレッドを作成し、ダウンロード プロセスがページの通常のレンダリングに影響を与えないようにすることもできます。
4. 添付ファイルはダウンロードする必要があり、ハードディスクに保存する必要はありませんが、Web アプリは添付ファイルを直接処理します。たとえば、pdf.js はダウンロードに ajax を使用します。
最後に、作者の ajax ダウンロード デモを紹介します: ajaxDownloadDemo_jb51.rar
上記は私がまとめたもので、将来的には皆さんのお役に立てれば幸いです。
関連記事:
単純なエンティティクラスとxmlファイルを相互に変換する方法
Ajaxを使用してRazorページを部分的に更新する(グラフィックチュートリアル)
AjaxFileUpload+Struts2でマルチファイルアップロード機能を実装する
以上がBlod に基づく Ajax プログレス バー ダウンロード実装サンプル コードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。