前端
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <input type="file" id="file"></body></html><script> document.getElementById('file').addEventListener('change', async (e) => { const file = e.target.files[0]; // 获取文件名 const file_name = file.name.split('.')[0] let cur = 0; let size = 1024 * 1024; const fileChunks = []; while (cur < file.size) { fileChunks.push({ file: file.slice(cur, cur + size) }) cur += size; } // 转成请求数组 里面每个都是formData const requestList = fileChunks .map(({ file }, index) => { const formData = new FormData(); formData.append('chunk', file); // 根据名称加下标格式发送 图片-1 formData.append('file_name', `${file_name}-${index}`) return { formData } }) .map(async ({ formData }) => request({ url: "http://localhost:3000", data: formData }) ) // 并发发送 await Promise.all(requestList) // console.log(requestList); await mergeRequest() }) // 封装请求 function request({ url, method = "POST", data, header = {}, requestList, // 上传文件列表 }) { return new Promise(resolve => { const xhr = new XMLHttpRequest(); // ajax对象 // 请求 xhr.open(method, url) // 设置请求头 Object.keys(header).forEach(key => { xhr.setRequestHeader(key, header[key]) }); // 发送数据 xhr.send(data) xhr.onload = e => { resolve({ data: e.target.response }) } }) } // 上传成功 合并切片 const mergeRequest = async () => { await request({ url: "http://localhost:3000/merge", header: { "content-type": "application/json" } }) alert('ok') }</script>
后端
const http = require('http');const path = require('path');// 处理表单const multiparty = require('multiparty')const server = http.createServer();const fse = require('fs-extra')// 要存放切片的地址const UPLOAD_URL = path.resolve(__dirname, 'target');server.on('request', async (req, res) => { res.setHeader('Access-Control-Allow-Origin', "*") res.setHeader('Access-Control-Allow-Method', "*") // res.end('ok') if (req.url === '/') { // 获取文件/名称; // 获取POST传过来的表单数据 const multipart = new multiparty.Form(); multipart.parse(req, async (err, fields, files) => { if (err) { return; } // 获取文件块 const [chunk] = files.chunk; // 获取文件名称 const [filename] = fields.file_name; // 切片后的名称 const dir_name = filename.split('-')[0]; // 文件名称地址 const chunkDir = path.resolve(UPLOAD_URL, dir_name) // 如果这个地址不存在 就创建一个吧 if(!fse.existsSync(chunkDir)){ await fse.mkdirs(chunkDir) } // 切片后的文件放到指定文件中夹 await fse.move(chunk.path,`${chunkDir}/${filename}`) console.log(chunkDir,filename); }) }else if(req.url === '/merge'){ // 把server/app.js里面合并的代码拿过来就可以 res.end('合并成功') }})server.listen(3000, () => console.log('http://localhost:3000'))