面试题 :前端实现切片上传的代码示例

面试题 :前端实现切片上传的代码示例

📌 温馨提示:
本文内容可能随时间变动而失效,请以页面显示的更新时间为准。
若内容已不准确或资源失效,欢迎留言或联系站长反馈修正。
⚠️ 免责声明:
本文仅供学习与参考,观点仅代表作者个人意见,与本站无关。
如有侵权问题,请立即联系我们处理,谢谢理解与支持。

下面为你提供使用原生 JavaScript 实现文件切片上传的代码示例,以及使用 axios 库实现文件切片上传的代码示例,主要思路是先将文件进行切片,然后依次上传每个切片,最后在服务器端合并这些切片。

原生 JavaScript 实现文件切片上传

前端代码(HTML + JavaScript)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件切片上传</title>
</head>

<body>
    <input type="file" id="fileInput">
    <button onclick="uploadFile()">上传</button>

    <script>
        const fileInput = document.getElementById('fileInput');

        function uploadFile() {
            const file = fileInput.files[0];
            if (!file) {
                alert('请选择文件');
                return;
            }

            const chunkSize = 1024 * 1024; // 每个切片大小为 1MB
            const totalChunks = Math.ceil(file.size / chunkSize);

            for (let i = 0; i < totalChunks; i++) {
                const start = i * chunkSize;
                const end = Math.min(start + chunkSize, file.size);
                const chunk = file.slice(start, end);

                const formData = new FormData();
                formData.append('file', chunk);
                formData.append('filename', file.name);
                formData.append('chunkIndex', i);
                formData.append('totalChunks', totalChunks);

                const xhr = new XMLHttpRequest();
                xhr.open('POST', '/upload', true);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        console.log(`第 ${i + 1} 个切片上传成功`);
                        if (i === totalChunks - 1) {
                            // 所有切片上传完成,发送合并请求
                            const mergeXhr = new XMLHttpRequest();
                            mergeXhr.open('POST', '/merge', true);
                            const mergeFormData = new FormData();
                            mergeFormData.append('filename', file.name);
                            mergeFormData.append('totalChunks', totalChunks);
                            mergeXhr.send(mergeFormData);
                        }
                    }
                };
                xhr.send(formData);
            }
        }
    </script>
</body>

</html>

后端代码(Node.js + Express)

const express = require('express');
const app = express();
const multer = require('multer');
const fs = require('fs');
const path = require('path');

const upload = multer({ dest: 'uploads/' });

// 处理切片上传
app.post('/upload', upload.single('file'), (req, res) => {
    const { filename, chunkIndex, totalChunks } = req.body;
    const chunkPath = path.join(__dirname, 'uploads', `${filename}.part${chunkIndex}`);
    fs.renameSync(req.file.path, chunkPath);
    res.send('切片上传成功');
});

// 处理切片合并
app.post('/merge', (req, res) => {
    const { filename, totalChunks } = req.body;
    const filePath = path.join(__dirname, 'uploads', filename);
    const writeStream = fs.createWriteStream(filePath);

    for (let i = 0; i < totalChunks; i++) {
        const chunkPath = path.join(__dirname, 'uploads', `${filename}.part${i}`);
        const readStream = fs.createReadStream(chunkPath);
        readStream.pipe(writeStream, { end: false });
        readStream.on('end', () => {
            fs.unlinkSync(chunkPath);
            if (i === totalChunks - 1) {
                writeStream.end();
                res.send('文件合并成功');
            }
        });
    }
});

const port = 3000;
app.listen(port, () => {
    console.log(`服务器运行在 http://localhost:${port}`);
});

使用 axios 库实现文件切片上传

前端代码(HTML + JavaScript)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件切片上传</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>

<body>
    <input type="file" id="fileInput">
    <button onclick="uploadFile()">上传</button>

    <script>
        const fileInput = document.getElementById('fileInput');

        async function uploadFile() {
            const file = fileInput.files[0];
            if (!file) {
                alert('请选择文件');
                return;
            }

            const chunkSize = 1024 * 1024; // 每个切片大小为 1MB
            const totalChunks = Math.ceil(file.size / chunkSize);

            for (let i = 0; i < totalChunks; i++) {
                const start = i * chunkSize;
                const end = Math.min(start + chunkSize, file.size);
                const chunk = file.slice(start, end);

                const formData = new FormData();
                formData.append('file', chunk);
                formData.append('filename', file.name);
                formData.append('chunkIndex', i);
                formData.append('totalChunks', totalChunks);

                try {
                    await axios.post('/upload', formData);
                    console.log(`第 ${i + 1} 个切片上传成功`);
                    if (i === totalChunks - 1) {
                        // 所有切片上传完成,发送合并请求
                        const mergeFormData = new FormData();
                        mergeFormData.append('filename', file.name);
                        mergeFormData.append('totalChunks', totalChunks);
                        await axios.post('/merge', mergeFormData);
                        console.log('文件合并成功');
                    }
                } catch (error) {
                    console.error(`第 ${i + 1} 个切片上传失败:`, error);
                }
            }
        }
    </script>
</body>

</html>

后端代码(Node.js + Express)

此部分后端代码与上面使用原生 XMLHttpRequest 时的后端代码相同,都是使用 Node.js 和 Express 框架,利用 multer 处理文件上传,fs 模块进行文件操作。

这些示例代码展示了前端如何将文件切片并上传,以及后端如何接收切片并合并成完整文件。在实际应用中,你可能需要根据具体需求对代码进行优化和扩展,例如添加错误处理、进度条显示、断点续传等功能。

THE END
喜欢就支持一下吧
点赞6
评论 抢沙发

请登录后发表评论

    暂无评论内容