reactjs - 上传块以使用 React 表达时,appendFileSync 未生成完整文件
问题描述
我正在尝试以快递方式实现块上传:
const cors = require('cors');
const express = require('express');
const md5 = require('md5');
const fs = require('fs');
const app = express()
const port = 4000
app.use(cors({origin: 'http://localhost:3000'}));
app.use(express.raw({type: 'application/octet-stream', limit: '100mb'}));
app.post('/upload', (req, res) => {
const { name, currentChunkIndex, totalChunks } = req.query;
const isFirstChunk = parseInt(currentChunkIndex) == 0;
const isLastChunk
= parseInt(currentChunkIndex) === parseInt(totalChunks) - 1;
const ext = name.split('.').pop();
const data = req.body.toString().split(',')[1];
const buffer = Buffer.from(data);
const tempFilename = 'tmp_' + md5(name + req.ip) + '.' + ext;
if (isFirstChunk && fs.existsSync('./uploads/' + tempFilename)) {
fs.unlinkSync('./uploads/' + tempFilename)
}
fs.appendFileSync('./uploads/' + tempFilename, buffer)
if (isLastChunk) {
const finalFileName = Date.now() + '.' + ext;
fs.renameSync('./uploads/' + tempFilename, './uploads/' + finalFileName);
}
res.send('ok');
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
我的反应调用使用以下工作人员:
import axios from 'axios';
const chunkSize = 1 * 1000000; //(10 MB)
const fileReader = blob => {
return new Promise((resolve, _) => {
const onloadHandler = e => {
const data = e.target.result;
resolve(data)
};
const reader = new FileReader();
reader.onload = e => onloadHandler(e);
reader.readAsDataURL(blob);
});
};
const uploadWorker = file => {
return new Promise(async(resolve, reject) => {
const totalChunks = Math.ceil(file.size / chunkSize);
console.log(`total chunks ${totalChunks}`);
let currentChunkIndex = 0;
while (currentChunkIndex < totalChunks) {
console.log(`current chunk ${currentChunkIndex}`);
const from = currentChunkIndex * chunkSize;
const to = Math.min(from + chunkSize, file.size);
const blob = file.slice(from, to);
const data = await fileReader(blob);
const params = new URLSearchParams();
params.set('name', file.name);
params.set('size', file.size);
params.set('currentChunkIndex', currentChunkIndex);
params.set('totalChunks', totalChunks);
const headers = {'Content-Type': 'application/octet-stream'};
const url = 'http://localhost:4000/upload?' + params.toString();
await axios.post(url, data, { headers });
currentChunkIndex += 1;
}
resolve();
});
};
export default uploadWorker;
当我在 express 上调试时,我可以看到它正确接收每个块,并且确实将数据保存到uploads
最终文件中,但它只是一个二进制文件,如果我尝试发送视频,我将无法观看视频。
与原始文件的 6.3mb 相比,保存的文件为 8.4mb...
有什么想法我在这里做错了吗?
解决方案
推荐阅读
- java - 使用 Mockito 模拟接口时出现空指针异常
- angular - 如何操作表格内的角度材料复选框
- javascript - JS找到对象数组之间的区别
- python - OpenCV查找轮廓的中间线[Python]
- javascript - 如何将数组与打字稿中的对象映射
- css - 将多个 CSS @keyframes 动画锁定在一起
- python - 使用变量更改列表内容
- c++ - 握手失败,出现致命错误 SSL_ERROR_SSL: error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER
- mysql - 对于单个数据库,每个网站都应该有不同的 MySQL 用户吗?
- python - Pandas:如何获取由另一列作为数据框分组的列上具有最大值的行