使用js+node实现分片上传功能

使用js将文件分片:

/**
 * 
 * @param {*} file       file是文件
 * @param {*} chunkSize  chunkSize是每个块的大小,默认64k
 * 方法的返回值是一个数组,数组里面的每个元素就是切好的块文件,可以直接上传
 */
function uploadFun(file, chunkSize=64 * 1024) {
    return new Promise((resolve) => {
        console.log(file);
        // 视频名字
        const fileName = new Date().getTime() + Math.floor(Math.random() * 150) + "_" + file.name

        console.log(fileName);
        console.log(chunkSize);
        let fileList = []

        let uploadSize = 0     // 当前上传了多少
        while (uploadSize < file.size) {
            const fileChunk = file.slice(uploadSize, uploadSize + chunkSize)
            const formData = createFormData({
                name: file.name,
                type: file.type,
                size: file.size,
                fileName: fileName,
                uploadSize: uploadSize,
                file: fileChunk,
                chunkSize
            })
            fileList.push(formData)
            uploadSize += fileChunk.size
        }
        resolve(fileList)
    })
}


// 创建分块文件
function createFormData({
    name,
    type,
    size,
    fileName,
    uploadSize,
    file,
    chunkSize
}) {
    const fd = new FormData()

    fd.append('name', name)
    fd.append('type', type)
    fd.append('size', size)
    fd.append('fileName', fileName)
    fd.append('uploadSize', uploadSize)
    fd.append('file', file)
    fd.append('chunkSize', chunkSize)

    return fd
}

在上述代码中,调用uploadFun方法会返回一个数组,数组的每一个元素就是对应的分片文件。

特别注意:使用uploadFun方法返回的数组去上传时,要使用同步调用,就是第一个分片文件上传完成之后,再上传下一个。

使用node+express将文件合并

以下时后端代码,在运行之前要安装包:

npm i express --save
npm i express-fileupload --save
const express = require('express');
const bodyParser = require('body-parser');
const uploader = require('express-fileupload');
const { resolve } = require('path');
const { existsSync, appendFileSync, writeFileSync } = require('fs');

const app = express()

const PORT = '4001'

app.use(bodyParser.urlencoded({
    extended: true
}))
app.use(bodyParser.json())
app.use(uploader())
app.use('/', express.static('upload_file'))

app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*')
    res.header('Access-Control-Allow-Headers', 'Authorization,X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method')
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PATCH, PUT, DELETE')
    res.header('Allow', 'GET, POST, PATCH, OPTIONS, PUT, DELETE')
    next();
})

app.post('/upload/fragment', (req, res) => {
    // console.log(req.body);
    if (!req.files) {
        res.send({
            code: 500,
            message: '请上传文件'
        })
        return
    }

    const filePath = resolve(__dirname, './upload_file/' + req.body.fileName)
    // 第一次上传,直接创建文件
    if (req.body.uploadSize == 0) {
        console.log(req.files.file);
        writeFileSync(filePath, req.files.file.data)
        res.send({
            code: 200,
            message: '文件已创建'
        })
        return
    }

    // 后续上传,追加    
    if(!existsSync(filePath)) {
        res.send({
            code: 500,
            message: '文件上传失败'
        })
        return
    }

    appendFileSync(filePath, req.files.file.data)

    // 最后一次,返回地址
    if (Number(req.body.uploadSize) + Number(req.body.chunkSize) >= Number(req.body.size)) {
        res.send({
            code: 200,
            message: '文件上传成功',
            data: {
                url: `http://127.0.0.1:4001/${req.body.fileName}`
            }
        })
        return
    }

    

    
    res.send({
        code: 200,
        message: '分段上传成功'
    })
})


app.listen(PORT, () => {
    console.log(`http://127.0.0.1:${PORT}`);
})

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值