Reputation: 131
I am using Nextjs to build my app. I am using AWS s3 to store my static files (images and PDFs,..)
I want user of my application to be able to download the file. I used the answer mentioned here to develop a solution and it worked but the image is not readable. It shows
It appears that we don't support this file format
Here is my script:
// /pages/api/getFile.js
import { NextApiRequest, NextApiResponse } from "next";
import stream from 'stream';
import { promisify } from 'util';
import s3 from "../../../../utils/s3-utils";
const pipeline = promisify(stream.pipeline);
export default async (req: NextApiRequest, res: NextApiResponse) => {
const bucketName = process.env.S3_UPLOAD_BUCKET || ""
const imageKey: any = req.query.imgkey
const downloadParams = {
Key: imageKey,
Bucket: bucketName
}
const downloadedObject = await s3.getObject(downloadParams).promise()
const readableFile= downloadedObject.Body?.toString('base64') || ""
const fileType= downloadedObject.ContentType || ''
res.setHeader('Content-Type', fileType);
res.setHeader('Content-Disposition', `attachment; filename=${imageKey}`);
await pipeline(readableFile, res);
}
from client:
<a href="/api/getFile">Download PDF</a>
Any idea what is the wrong here?
Upvotes: 2
Views: 5479
Reputation: 131
Here is the answer:
I was able to simply solve it by using createReadStream()
and piping the response stream with using the proper response header
import s3 from "../../../../utils/s3-utils";
export default async (req: NextApiRequest, res: NextApiResponse) => {
const bucketName = process.env.S3_UPLOAD_BUCKET || ""
const imageKey: string = req.query.imgkey.toString()
const imageFormat = imageKey.split(".")[1]
const downloadParams = {
Key: imageKey,
Bucket: bucketName
}
const readableObject = s3.getObject(downloadParams).createReadStream()
res.setHeader('Content-Type', `image/${imageFormat}`);
res.setHeader('Content-Disposition', `attachment; filename=${imageKey}`);
readableObject.pipe(res)
}
Upvotes: 5