LoginSignup
0
1

More than 1 year has passed since last update.

ファイルダウンロードのAPIリクエスト送信を実装してみたら無限ループになった件

Last updated at Posted at 2021-06-09

問題

ダウンロードボタンを一回押したら、無限に自動ダウンロードすることになりました

<a id="id1" href="javascript:void(0)" onclick="handleDownload('/', 1)">ダウンロード</a>
const downloadFile = (path, params) =>
    new Promise((resolve, reject) => {
        axios({
            url: path,
            method: 'GET',
            responseType: 'blob',
            params: params,
        }).then((res) => {
            const url = URL.createObjectURL(new Blob([res.data], { type: 'text/csv' }));
            const link = document.getElementByID('id1');
            link.href = url;
            const filename = 'filename'; //なんらかのファイル名処理
            link.setAttribute('download', `${filename}.csv`);
            link.click();
            URL.revokeObjectURL(url);
        }).then((res) => {
            resolve(res);
        }).catch((e) => {
            reject(e);
        });
    });

const handleDownload = (path, id) => {
    const params = {
        id: id,
    }
    await downloadFile(path, params).catch((e) => window.alert(e));

原因

ボタン押下する → onclickイベント着火 → handleDownload実行 → link.click()実行 → aタグのonclickイベント着火 → handleDownload実行 → link.click()実行 → aタグのonclickイベント着火...
の無限ループに入ります!

解決方法

<span onclick="handleDownload('/', 1)">ダウンロード</span>
/**
* downloadFile関数の中でgetElementでaタグ要素を取得するのではなく、
* 代わりにjsの中でaタグ要素を作成して、ダウンロード実行の後に削除する
*/
const link = document.createElement('a');
...
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(url);
link.parentNode.removeChild(link);
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1