微信公众号
扫描关注微信公众号
博客大厅

后端返回文件流,前端怎么下载

原创 来源:博客站 阅读 0 01月21日 17:11 听全文

在Web开发中,当后端返回文件流时,前端需要处理这个响应以触发文件下载。这通常涉及发送一个HTTP请求到后端,接收响应中的文件数据,并创建一个下载链接来触发浏览器的下载行为。以下是实现这一功能的常见步骤,使用JavaScript和Fetch API作为示例。

后端示例(假设使用Node.js和Express)

首先,确保后端能够发送文件流。以下是一个简单的Node.js/Express示例:

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
const port = 3000;

app.get('/download', (req, res) => {
    const filePath = path.join(__dirname, 'example.txt'); // 替换为实际文件路径
    const fileName = 'downloaded_example.txt'; // 客户端下载的文件名
    const stat = fs.statSync(filePath);
    const fileSize = stat.size;
    const range = req.headers.range;

    if (range) {
        const parts = range.replace(/bytes=/, "").split("-");
        const start = parseInt(parts[0], 10);
        const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;

        if (start >= fileSize || end >= fileSize) {
            return res.status(416).send("Requested Range Not Satisfiable");
        }

        const chunkSize = (end - start) + 1;
        const file = fs.createReadStream(filePath, { start, end });
        const head = {
            'Content-Range': `bytes ${start}-${end}/${fileSize}`,
            'Accept-Ranges': 'bytes',
            'Content-Length': chunkSize,
            'Content-Type': 'text/plain',
            'Content-Disposition': `attachment; filename=${fileName}`
        };

        res.writeHead(206, head);
        file.pipe(res);
    } else {
        const head = {
            'Content-Length': fileSize,
            'Content-Type': 'text/plain',
            'Content-Disposition': `attachment; filename=${fileName}`
        };
        res.writeHead(200, head);
        fs.createReadStream(filePath).pipe(res);
    }
});

app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}/`);
});

前端示例(使用Fetch API)

在前端,你可以使用Fetch API来发送请求并处理响应。以下是一个使用JavaScript和Fetch API的示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Download Example</title>
</head>
<body>
    <button id="downloadButton">Download File</button>

    <script>
        document.getElementById('downloadButton').addEventListener('click', async () => {
            const url = 'http://localhost:3000/download'; // 后端提供文件下载的URL

            try {
                const response = await fetch(url, {
                    method: 'GET',
                    headers: {
                        'Range': 'bytes=0-' // 可选:指定请求的文件范围,用于支持断点续传
                    }
                });

                if (!response.ok) {
                    throw new Error(`HTTP error! Status: ${response.status}`);
                }

                const blob = await response.blob();
                const urlObject = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.style.display = 'none';
                a.href = urlObject;
                a.download = 'downloaded_example.txt'; // 设置下载的文件名
                document.body.appendChild(a);
                a.click();

                setTimeout(() => {
                    window.URL.revokeObjectURL(urlObject);
                    document.body.removeChild(a);
                }, 0);
            } catch (error) {
                console.error('There was a problem with the fetch operation:', error);
            }
        });
    </script>
</body>
</html>

解释

  1. 后端

    • 设置了一个/download路由,用于发送文件流。
    • 根据请求头中的Range字段,支持断点续传(可选)。
    • 设置适当的响应头,包括Content-Disposition以触发下载行为。
  2. 前端

    • 使用Fetch API发送GET请求到后端下载URL。
    • 将响应转换为Blob对象。
    • 创建一个隐藏的<a>元素,设置其href为Blob对象的URL,并设置download属性为期望的文件名。
    • 程序触发点击事件以下载文件。
    • 清理:释放Blob对象的URL并从DOM中移除<a>元素。

通过这种方式,你可以实现从后端发送文件流到前端并触发下载的功能。

学在每日,进无止境!更多精彩内容请关注微信公众号。
原文出处: 内容由AI生成仅供参考,请勿使用于商业用途。如若转载请注明原文及出处。
出处地址:http://www.07sucai.com/tech/158.html
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。
>