フロントエンドがファイルをダウンロードするためのさまざまな方法

フロントエンドに関係するファイル ダウンロードのアプリケーション シナリオはまだたくさんあります。では、フロントエンド ファイルのダウンロードには何通りの方法があるでしょうか? それぞれの方法の長所と短所は何ですか? 一つずつ紹介していきましょう。

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のホームページにジャンプします。

ここでのポイントは、新たに追加したalabel のdownload属性ですHTML5

ダウンロードするファイル名を指定する機能です。指定しない場合は、リクエストの内容に応じてダウンロードされるファイル名がContent-Disposition決定されます。指定しない場合はContent-DispositionURLリクエストの最後の部分がファイル名として使用されます。

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.xhtmlhtml

同様に、クロスドメイン ファイルは、結局のところ、ダウンロードできません (はい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に変換しダウンロードタグの作成するというものです。blobURL.createObjectURLurladownload

ここには 2 つの知識ポイントがあり、1 つはblobオブジェクト、もう 1 つはオブジェクトですURL.createObjectURL

5.1 ブロブ

blobMDN [2] からのオブジェクトの定義は次のとおりです。

Blobオブジェクトは、不変のプリミティブ データのファイルのようなオブジェクトを表します。そのデータはテキストまたはバイナリ形式で読み取ることができ、 ReadableStream データ操作のために変換することもできます。

BlobJavaScriptデータをネイティブ形式で表す必要はありません。File このインターフェイスは に基づいており Blobblob機能を継承し、ユーザーのシステム上のファイルをサポートするように拡張されています。

blobObject は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)

ここで注意する必要があるのは、urlthis のライフ サイクルはそれを作成したウィンドウにバインドされているdocument、つまり、documentthis が破棄されるurlと無効になるため、適切なタイミングで破棄する必要があるということです。以下のとおりであります:

URL.revokeObjectURL(url)

ダウンロードしたばかりの問題に戻りますが、blobオブジェクトを通じて解決しますが、type属性はハードコーディングされています。ファイルの種類が決定されている場合は問題ありませんが、このインターフェイスがファイルをダウンロードするためのインターフェイスである場合、ファイルが存在する可能性があります。色々な種類があるのですが、どのように対処すれば良いのでしょうか?

ここには正解はありません。最初のものは、インターフェイス プロバイダーとネゴシエートできます。ネゴシエーション プランは不確実です。2 つ目は、インターフェイス プロバイダーを介してファイルを取得することです。responseこれheadertype私たちが話したいことです。

const type = response.headers['content-type']

const blob = new Blob([response.data], { type })

ここではファイルを正しくダウンロードできるように、 を通じてそれを取得し、オブジェクトをresponse作成headerします。typeblob

実際、現時点ではファイルを取得する必要content-typeがあるかもしれませんapplication/octet-streamfile-typetype

file-typeファイルを取得するために次のコードが渡されますtype

import {fileTypeFromStream} from 'file-type';

const type = await fileTypeFromStream(response.body);
const blob = new Blob([response.data], { type })

6. まとめ

上記には非常に多くの解決策がありますが、実際、a最終的にはまだラベルに記載されているため、ブラウザーの組み込み動作を通じてダウンロードされるか、ajaxダウンロードを通じてダウンロードされるかに関係なく、最終的なファイルのダウンロードはブラウザーの動作になります。

- -終わり - -

おすすめ

転載: blog.csdn.net/qq_44848480/article/details/129236595