Javascripだけでファイルのダウンロードをやってみた

写真公開プログラムver5の開発中。入力情報の一時保存の方法を調べてたら、Javascriptでファイルのダウンロードができるっぽいのでやってみた。

方法としては、aタグにdownload属性を追加していい感じに設定するといいらしい。
なので早速やってみた

const compressedData = pako.gzip(data);
// ダウンロード
const downloadURL = URL.createObjectURL(new Blob([compressedData], { type: 'application/gzip' }));
const downloadLink = document.createElement('a');
document.body.appendChild(downloadLink);
downloadLink.download = 'data.gz';
downloadLink.href = downloadURL;
downloadLink.click();
downloadLink.remove();
URL.revokeObjectURL(downloadURL);

dataには保存したい情報を入れておく。データはでかいのでpakoでgzip圧縮。
URL.createObjectURLで圧縮データをダウンロードするためのURLを作成。
aタグを作ってbodyに配置。downloadにファイル名を、hrefにcreateObjectURLの戻り値をセット。
それを.click()でクリックイベントを発火させるとダウンロード確認のダイアログが出る。
イベントを発火させたら、removeでaタグを削除してURL.revokeObjectURLでURLを削除して完了。
おまけ:ダウンロードしたファイルの復元。

const upload = (event: React.DragEvent) => {
        event.stopPropagation();
        event.preventDefault();
        const uploadFiles = Array.from(event.dataTransfer.files) as File[];
        if (/.gz$/.test(uploadFiles[0].name)) {
            // 一時保存のリストア
            const storeFile = uploadFiles[0];
            const reader = new FileReader();
            reader.onload = (result) => {
                const decompressedData = new TextDecoder('utf-8')
                    .decode(pako.ungzip(new Uint8Array(result.target.result as ArrayBuffer)));
                const restoreData: RestoreData = JSON.parse(decompressedData);
                setPhotoList(restoreData.data);
            };
            reader.readAsArrayBuffer(storeFile);
        }
}
<section className="upload">
    <div
        onDragEnter={(e: React.DragEvent) => { e.stopPropagation(); e.preventDefault(); }}
        onDragOver={(e: React.DragEvent) => { e.stopPropagation(); e.preventDefault(); }}
        onDrop={upload}
        style={{ height: '10em', backgroundColor: '#cccccc' }}
    />
</section>

divのondropイベントハンドラでgzファイルのドラッグアンドドロップを受付。
FileReaderreadAsArrayBufferで読み込んだデータをpakoでデコードしてstateに入れてReactにレンダリング要求して完了。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です