前端切片上传文件,后端接受合并文件。这里后端使用的是Koa2.
安装koa2 1 2 npm i koa2 -g koa2 demo && cd demo && npm i
koa-body 1 2 3 4 5 6 7 8 9 10 11 npm i -S koa-body /* 提供了文件上传功能,处理post请求数据 所以需要在app.js中 把 bodyparser 注释了(并且二者不能共存,会导致post请求超时) ` // app.use(bodyparser({ // enableTypes:['json', 'form', 'text'] // })) ` */
1 2 3 4 5 6 7 8 app.use (koaBody ({ multipart :true , formidable :{ uploadDir :path.join (__dirname,"static" ), keepExtensions :true } }))
前端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > upload</title > </head > <script src ="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js" > </script > <body > <input type ="file" name ="" id ="" > <button class ="submit" > submit</button > </body > <script > let file; document .querySelector ("input" ).onchange =(e )=> { file = e.target .files [0 ] } document .querySelector (".submit" ).onclick = (e )=> { if (!file)return upload () } function spliceFile ( ){ let {size} = file; let count = 5 let i = 1 ; let s = 0 let FileBolbArr = [] while (i<=count){ let e = size/count*i; FileBolbArr .push (file.slice (s,e)) s = e i++; } return FileBolbArr } function upload ( ){ const ajax = axios.create ({ baseURL :"http://127.0.0.1:4000" , timeout : 1000 * 60 , }) let promiseArr = spliceFile ().map ((e,i )=> { if (e.isupload )return let obj = new FormData () obj.append ("bolb" ,e) obj.append ("index" ,i) return ajax.post ("/upload" ,obj) }) Promise .all (promiseArr).then (res => { ajax.post ("/end" ,{filepath :file.name }) }).catch (e => { console .log (e,'error' ); }) } </script > </html >
后端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 const fs = require ('fs' )router.post ("/upload" ,async (ctx,next)=>{ let { body } = ctx.request upload.push ({ path :ctx.request .files .bolb .path , index :body.index }) ctx.body = {msg :"ok" } }) router.post ("/end" ,async (ctx,next)=>{ let { filepath } = ctx.request .body let data = upload.sort ((a,b )=> a.index -b.index ) let files = data.map (e => e.path ) fs.writeFileSync (`static/${filepath} ` ,"" ) let write = fs.createWriteStream (`static/${filepath} ` ) let merge = ( )=>{ if (!data.length ){ files.map (e => fs.unlinkSync (e)) console .log ('merge sucess' ); return } let read = fs.createReadStream (data.shift ().path ) read.pipe (write,{end :false }) read.on ('end' ,()=> { merge () }) } merge () ctx.body = {msg :"ok" } })
最后 这个demo就到这里了,未完成功能 多文件上传,断点续传(axios的canceltoken),electron制作个人网盘