Issue with res.download()

24 Views Asked by At

I've problems trying to apply res.download(filePath, originalName) with Multer, since it saves/copies a file from the /uploads folder to /downloads with fs.copyFile() when I apply my logic to it but, for the purpose client, you do not receive the browser opening to allow you to save your file.

Any ideas? On front, I don't receive anything... Am I making the request wrong? Thanks!

Request:

server.get('/download/:fileId', downloadFileHandler)

downloadFileHandler:

export default async (req, res, next) => {
    const token = req.headers.authorization.substring(7)
    const { sub: userId } = jwt.verify(token, process.env.JWT_SECRET)

    const { fileId } = req.params

    try {
        const file = await downloadFile(userId, fileId)
        const { path, originalName } = file

        res.download(path, originalName)
    } catch (error) {
        let status = 500
............REST CODE ERROR...............


downloadFile logic:

export default async function downloadFile(userId, fileId) {

    try {
        const user = await User.findById(userId).lean()
        if (!user) {
            throw new NotFoundError('User not found')
        }

        const file = await File.findById(fileId).lean()
        if (!file) {
            throw new NotFoundError('File not found')
        }

        // const isOwner = user.id === file.owner
        // const isAdmin = user.role && user.role.includes('admin')

        if (file.owner[0] === user.id || user.role[0] === 'admin') {
            const originalName = file.name
            const oldPath = `./uploads/${file._id.toString()}`
            const newPath = `./downloads/${originalName}`

            await fs.copyFile(oldPath, newPath)

            return { path: newPath, originalName }
        } else {
            throw new AuthorizationError('Authorization denied. Try again')
        }

    } catch (error) {


A solution to res.download() with MULTER

1

There are 1 best solutions below

0
Abel Prieto Martín On BEST ANSWER

I could solve this converting file data with .blob() method.

Thats my code:

function handleDownloadFile(event) { event.preventDefault()

const clientError = document.querySelector(props.clientError)

try {
    logic.downloadFile(file.id)
        .then(blob => {
            const url = window.URL.createObjectURL(blob)

            const anchor = document.createElement('a')
            anchor.href = url
            anchor.download = file.name
            anchor.click()

            window.URL.revokeObjectURL(url)

            clientError.innerText = 'File successfully download ✅'
            clientError.style.color = 'green'
        })
} catch (error) {
    clientError.innerText = `${error.message} ❌`
    clientError.style.color = 'tomato'

    handleError(error, navigate)
}