フロントエンドに関係するファイル ダウンロードのアプリケーション シナリオはまだたくさんあります。では、フロントエンド ファイルのダウンロードには何通りの方法があるでしょうか? それぞれの方法の長所と短所は何ですか? 一つずつ紹介していきましょう。
1. ラベル
a
これは、 label の属性を使用してdownload
ファイルのダウンロードを実現する最も簡単な方法であり、私たちが使用する一般的な方法でもあります。最初にサンプル コードを見てみましょう:
<a href="http://www.baidu.com" download="baidu.html">下载</a>
上の例では、[ダウンロード] をクリックすると、Baidu のホームページにジャンプし、実際にはファイルがダウンロードされていないことがわかりました。
タグ ダウンロードでは同じ生成元のファイルのみをダウンロードできるためa
、クロスドメイン ファイルの場合、画像、オーディオ、ビデオなどのメディア ファイルが含まれますが、これらはすべてプレビューであり、ダウンロードできません。
上記のコードはa
ラベルを書くことで直接ファイルのダウンロードを実現するものですが、書くことで実現することもできますjs
。コードは次のとおりです。
const a = document.createElement('a')
a.href = 'http://www.baidu.com'
a.download = 'baidu.html'
a.click()
効果は上記と同じで、すべてファイルをダウンロードせずにBaiduのホームページにジャンプします。
ここでのポイントは、新たに追加したa
label のdownload
属性ですHTML5
。
ダウンロードするファイル名を指定する機能です。指定しない場合は、リクエストの内容に応じてダウンロードされるファイル名がContent-Disposition
決定されます。指定しない場合はContent-Disposition
、URL
リクエストの最後の部分がファイル名として使用されます。
2. 窓を開く
a
タグを使用する上記のケースはwindow.open
、同じ効果を使用して実現することもできます。コードは次のとおりです。
window.open('http://www.baidu.com', '_blank')
ここで_blank
指定された開き方は、指定されていない場合は現在のページで開き、ここで指定されている場合は_blank
新しいページで開きます。
同じa
タグの属性download
も使用できます。コードは次のとおりです。
window.open('http://www.baidu.com', '_blank', 'download=baidu.html')
もちろん、この方法にも欠陥があり、タグと比較すると、 、 、、およびその他のファイルはファイルとして扱われ、現在のページで直接開かれるため、a
この方法ではダウンロードできません.html
。.htm
.xml
.xhtml
html
同様に、クロスドメイン ファイルは、結局のところ、ダウンロードできません (はいwindow.open
、いいえwindow.download
(window.download
仮説))。
3. location.href
このメソッドはwindow.open(url)
それと同じで、コードは次のとおりです。
location.href = 'http://www.baidu.com'
この方法にはwindow.open
すべての欠陥があるため、使用はお勧めできません。ここでは理解のためだけに説明するので、あまり説明しません。
4. 場所.? その他の属性
location.assign
ここでのその他のプロパティは、 、location.replace
などのページにジャンプできるプロパティを指しますlocation.reload
。これらのプロパティはファイルのダウンロードを実現できます。コードは次のとおりです。
location.assign('http://www.baidu.com')
location.replace('http://www.baidu.com')
location.reload('http://www.baidu.com')
ここlocation.reload
は少し特殊で、その機能は現在のページをリロードすることですが、パラメーターを受け入れることもできます。このパラメーターはジャンプするページであるため、ファイルのダウンロードも実現できます。
もちろんlocation.href
、これらの方法の欠点は同じであり、それぞれの属性の特性もありますが、これは知識を広げるためのものであり、あまり説明しすぎるものではありません。
5. XMLHttpRequest
このメソッドは、私たちがよくajax
ダウンロードと呼ぶもので、axios
などfetch
も同じで、コードは次のとおりです。
const xhr = new XMLHttpRequest()
xhr.open('GET', 'http://www.baidu.com')
xhr.send()
xhr.onload = function () {
const blob = new Blob([xhr.response], { type: 'text/html' })
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = 'baidu.html'
a.click()
}
ここではXMLHttpRequest
関連知識については説明せず、ファイルのダウンロードに関連する部分についてのみ説明します。
response
ここでの主なロジックは、リクエストが成功すると、ダウンロードしたいコンテンツであるレスポンスボディを取得し、それをオブジェクトresponse
に変換し、ダウンロードタグの作成するというものです。blob
URL.createObjectURL
url
a
download
ここには 2 つの知識ポイントがあり、1 つはblob
オブジェクト、もう 1 つはオブジェクトですURL.createObjectURL
。
5.1 ブロブ
blob
MDN [2] からのオブジェクトの定義は次のとおりです。
Blob
オブジェクトは、不変のプリミティブ データのファイルのようなオブジェクトを表します。そのデータはテキストまたはバイナリ形式で読み取ることができ、ReadableStream
データ操作のために変換することもできます。
Blob
JavaScript
データをネイティブ形式で表す必要はありません。File
このインターフェイスは に基づいておりBlob
、blob
機能を継承し、ユーザーのシステム上のファイルをサポートするように拡張されています。
blob
Object はhtml5
新しく追加されたオブジェクトで、写真、ビデオ、オーディオなどのバイナリ データを保存する機能があります。その使用方法は次のとおりです。
/**
* @param {Array} array 二进制数据
* @param {Object} options 配置项
* @param {String} options.type 文件类型,它代表了将会被放入到 blob 中的数组内容的 MIME 类型。
* @param {String} options.endings 用于指定包含行结束符\n的字符串如何被写入。默认为transparent,表示不会修改行结束符。还可以指定为native,表示会将\n转换为\r\n。
*/
const blob = new Blob([], { type: '' })
ここでの主な関心はtype
属性です。デフォルトでは、blob
オブジェクトにはtype
属性がありません。したがって、これはBlob
タイプレスBlob
ファイルです。ファイルが破損することはありませんが、正常に認識できません。
5.2 URL.createObjectURL
以下は MDN [3] からの抜粋です。
URL.createObjectURL() 静的メソッドは、パラメーターで指定されたオブジェクトを表す URL を含む DOMString を作成します。この URL の有効期間は、それを作成したウィンドウ内のドキュメントにバインドされています。この新しい URL オブジェクトは、指定された File オブジェクトまたは Blob オブジェクトを表します。
このメソッドは、 を作成するために使用されますurl
。その機能は、blob
オブジェクトを 1 つに変換することですurl
。このメソッドはurl
、ファイルのダウンロードまたはファイルのプレビューに使用できます。コードは次のとおりです:
const url = URL.createObjectURL(blob)
ここで注意する必要があるのは、url
this のライフ サイクルはそれを作成したウィンドウにバインドされているdocument
、つまり、document
this が破棄されるurl
と無効になるため、適切なタイミングで破棄する必要があるということです。以下のとおりであります:
URL.revokeObjectURL(url)
ダウンロードしたばかりの問題に戻りますが、blob
オブジェクトを通じて解決しますが、type
属性はハードコーディングされています。ファイルの種類が決定されている場合は問題ありませんが、このインターフェイスがファイルをダウンロードするためのインターフェイスである場合、ファイルが存在する可能性があります。色々な種類があるのですが、どのように対処すれば良いのでしょうか?
ここには正解はありません。最初のものは、インターフェイス プロバイダーとネゴシエートできます。ネゴシエーション プランは不確実です。2 つ目は、インターフェイス プロバイダーを介してファイルを取得することです。response
これheader
がtype
私たちが話したいことです。
const type = response.headers['content-type']
const blob = new Blob([response.data], { type })
ここでは、ファイルを正しくダウンロードできるように、 を通じてそれを取得し、オブジェクトをresponse
作成header
します。type
blob
実際、現時点ではファイルを取得する必要content-type
があるかもしれません。application/octet-stream
file-type
type
file-type
ファイルを取得するために次のコードが渡されますtype
。
import {fileTypeFromStream} from 'file-type';
const type = await fileTypeFromStream(response.body);
const blob = new Blob([response.data], { type })
6. まとめ
上記には非常に多くの解決策がありますが、実際、a
最終的にはまだラベルに記載されているため、ブラウザーの組み込み動作を通じてダウンロードされるか、ajax
ダウンロードを通じてダウンロードされるかに関係なく、最終的なファイルのダウンロードはブラウザーの動作になります。
- -終わり - -