【入門者向け】Chat GPTに色々教えてもらいながらAWS S3にあるファイルをダウンロードしてみる【4章: ダウンロード編】

# 記事の目的

- 初学者でもAmazon S3(以降S3)について理解を深められるようにする
- S3を使って画像をアップロードできるアプリケーションを作成できるようにする

**関連記事**
[1章: バケット作成編](https://qiita.com/miumi/items/58fdb6cc3809f4203ef9)
[2章: アクセス許可の設定編](https://qiita.com/miumi/items/c07cb9bf958de7c7bb2a)
[3章: アップロード編](https://qiita.com/miumi/items/017d7595c724d03c4227)
[4章: ダウンロード編](https://qiita.com/miumi/items/4638d7c1034c229abb3a) ←今ここ

※この記事の内容は3章の続きからになります

# 1.ブラウザからダウンロードできるようにするには？
早速聞いてみました。コードは[3章](https://qiita.com/miumi/items/017d7595c724d03c4227)のものを引用

![スクリーンショット 2023-09-16 13.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/7a212e21-f5b3-06aa-d37c-724fb26dda39.png)
![スクリーンショット 2023-09-16 13.52.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/e46696bf-bb12-0862-90dd-3c16e67d03a4.png)
![スクリーンショット 2023-09-16 13.52.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/856141f1-4116-3e63-2c9e-381406f4a88d.png)


# 2.コーティング
```app.js
// ここから追加
router.get('/download/:key', (req, res) => {
    const key = req.params.key;

    const params = {
        // バケット名を入力。チーム開発する時はバケット名は公開しないようにenv等で管理してください
        Bucket: 'xxxxxx',
        Key: key,
    };

    // S3からファイルを取得してレスポンスに書き込む
    s3.getObject(params, (err, data) => {
        if (err) {
            console.error('S3ダウンロードエラー:', err);
            return res.status(500).json({ success: false, message: 'ダウンロードエラーが発生しました。' });
        }

        // ファイルのデータと適切なヘッダーをレスポンスに設定
        res.setHeader('Content-Disposition', `attachment; filename="${key}"`);
        res.setHeader('Content-Type', data.ContentType);

        // ファイルデータをレスポンスに書き込む
        res.send(data.Body);
    });
});
// ここまで追加

const app = express();
```

```public/index.html
<!-- 追加 -->
<a href="#" id="downloadLink" style="display: none">ダウンロード</a>

  <script>
    function uploadFile() {
      // 省略
    }

    // ここから追加
      function downloadFile(key) {
        fetch(`/download/${key}`, {
          method: 'GET',
          mode: 'cors'
        })
          .then(response => {
            // ファイルをダウンロードするためのリンクを生成
            const downloadLink = document.getElementById('downloadLink');
            downloadLink.href = URL.createObjectURL(response.blob());
            downloadLink.download = key;
            downloadLink.style.display = 'block';
          })
          .catch(error => {
            console.error('ダウンロードエラー:', error);
          });
      }
  </script>
```


# 3.ダウンロードしてみる

エンドポイントは/download/:keyになると思いますが、:keyが何を指すのか確認
![スクリーンショット 2023-09-16 14.12.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/55b54885-8938-ac4a-606f-00e611009956.png)

なるほど!S3の詳細画面確認できるキーですね。
キーとは何かに関しては[こちらの記事の画像](https://www.sbbit.jp/article/cont1/58205)がわかりやすかったので引用します
![l_bit202104121527291086.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/33d07d97-1c85-393c-4a09-d87414b77fb0.png)

node app.jsでサーバーを再起動して`http://localhost:3000/download/${キー名}`でブラウザからアクセスすると・・・
![スクリーンショット 2023-09-16 14.14.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/79f02ac0-5257-a32e-a885-f316bccff1f2.png)

ダウンロードできました！
実際のプロダクトではS3ファイルを一覧でfetchしてきて、ボタン等をクリックしたときに該当するファイルをダウンロードする処理になると思います。


# 終わりに
これでS3編は終わりになります。
AWSに興味あるけど、どうやって勉強すればいいんだろう・・・？と思った方の参考になれば幸いです！