面试题答案
一键面试- 文件分片:
- 使用
File API
中的File.prototype.slice
方法来对大文件进行分片。例如:
const file = document.getElementById('fileInput').files[0]; const chunkSize = 1024 * 1024; // 1MB 每片 const totalChunks = Math.ceil(file.size / chunkSize); const chunks = []; 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); chunks.push(chunk); }
- 使用
- 记录断点信息:
- 在客户端,我们可以维护一个状态对象来记录上传进度。例如,在 React 组件的
state
中:
this.state = { uploadedChunks: [], currentChunkIndex: 0 };
- 当每一个分片成功上传后,将其索引添加到
uploadedChunks
数组中。 - 对于服务器端,每次成功接收一个分片后,可以将已接收的分片信息记录在数据库中,比如使用 MongoDB 的文档存储每个文件已上传的分片序号等信息。
- 在客户端,我们可以维护一个状态对象来记录上传进度。例如,在 React 组件的
- 断点续传:
- 客户端:
- 在重新开始上传时,检查
state
中的uploadedChunks
数组,从上次中断的位置开始上传。例如:
const resumeUpload = () => { const { uploadedChunks, currentChunkIndex } = this.state; for (let i = currentChunkIndex; i < chunks.length; i++) { if (!uploadedChunks.includes(i)) { const chunk = chunks[i]; // 这里使用 Fetch API 上传分片 fetch('/upload', { method: 'POST', body: chunk, headers: { 'Content-Type': 'application/octet-stream', 'X-File-Name': file.name, 'X-Chunk-Index': i } }) .then(response => response.json()) .then(data => { if (data.success) { this.setState(prevState => ({ uploadedChunks: [...prevState.uploadedChunks, i], currentChunkIndex: i + 1 })); } else { // 处理上传失败情况 } }); } } };
- 在重新开始上传时,检查
- 服务器端:
- 在接收上传请求时,根据请求头中的
X-File-Name
和X-Chunk-Index
来判断该分片是否已上传。如果已上传,则跳过;如果未上传,则处理该分片的上传逻辑。例如在 Node.js 中使用 Express:
const express = require('express'); const app = express(); const bodyParser = require('body-parser'); app.use(bodyParser.raw({ type: 'application/octet-stream' })); app.post('/upload', (req, res) => { const fileName = req.get('X-File-Name'); const chunkIndex = parseInt(req.get('X-Chunk-Index')); // 这里从数据库检查该分片是否已上传 // 假设这里有一个函数 checkChunkUploaded 来检查 if (checkChunkUploaded(fileName, chunkIndex)) { return res.json({ success: true }); } // 处理上传逻辑,保存分片到文件等 // 假设这里有一个函数 saveChunk 来保存分片 saveChunk(req.body, fileName, chunkIndex); res.json({ success: true }); });
- 在接收上传请求时,根据请求头中的
- 客户端: