Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9409

Express.jsでファイルダウンロード

$
0
0

Express.jsで画像などのファイルをダウンロードする方法です。
本記事の内容は以下のドキュメントに書かれている内容の説明になります。
https://expressjs.com/ja/api.html

実行環境

express.js 4.17.1
MacOS 10.15.7

方法その1 簡易的な方法

importexpressfrom'express';exportconstrouter:express.Router=express.Router()router.get('/download',(req,res)=>{res.download('images/どね.jpg')})

downloadメソッドを使います。ファイルパスを引数に取ることになるので、一度ファイルをストレージのどこかに置く必要があります。すでにBuffer形式になっている場合は少し面倒ですね。

方法その2 headerに指定

importexpressfrom'express';importfsfrom'fs/promises'exportconstrouter:express.Router=express.Router()router.get('/set',async(req,res)=>{constimg=awaitfs.readFile('images/どね.jpg')constfileName=encodeURIComponent('どね.jpg')res.set({'Content-Disposition':`attachment; filename=${fileName}`})res.status(200).send(img)})

レスポンスのヘッダーを直接指定します。Content-Dispositionattachmentを指定することでブラウザ側でダウンロードファイルであることを認識してくれます。
それ以外にも以下の処理が必要になります。

  • Bufferファイルを一度読み込んでbodyに入れる
  • 日本語ファイル名の可能性がある場合はファイル名にエンコードをかける

filenameとfilename*の違いについて

引数の filename と filename* の違いは、 filename* が RFC 5987 で定義されているエンコーディングを使用するという点のみです。単一のヘッダーフィールドの値に filename と filename* の両方が存在する場合は、両方が解釈できる場合、 filename* が filename よりも優先されます。

方法1ではfilename*が自動で使われて、方法2ではどちらも指定できます。

方法1方法2
image.pngimage.png

いくつかのブラウザで試しましたがすべてfilename*を認識できていました。使える文字もこちらのほうが多いようです。あえてfilenameを使う必要はなさそうです。もし使えないブラウザがあったら教えていただきたいです。

試したブラウザを以下に置いておきます。

ブラウザバージョン対応状況
Chrome88
FireFox88
Microsoft Edge88
Internet Explorer11

まとめ

たいていはフレームワークに乗っかった方が後々困ることもないので方法1推奨です。
修正がかかったらフレームワーク側を直せば良い話ですし。


Viewing all articles
Browse latest Browse all 9409

Trending Articles