首页 > 其他分享 >koa上传下载文件

koa上传下载文件

时间:2023-04-16 18:46:07浏览次数:46  
标签:文件 fs koa 上传下载 ctx fileName url let file

1、koa上传文件

前端:

input标签的files中获取file类型(比如饿了么的raw),file类型是一种特殊的blob类型,通过加入FormData类型中,通过FormData传给后端

let blob = file类型(从type为file的input的value中的files数组中获取)
let formdata = new FormData()
formdata.append('file', blob)
ajax.post('/file/up', formdata)

后端:

通过koa-body的ctx.request.files.file接受到文件,通过fs的readFileSync读取文件的filepath获取数据,再通过fs的writeFileSync把数据写入指定的目录,返回url(实际会保存路径做处理,这里只是简单展示)

            let file = ctx.request.files.file
            let obj = {}
            if (Object.prototype.toString.call(file) == '[object Array]') {
                obj.url = []
                file.map(e => {
                    let data = fs.readFileSync(e.filepath)
                    fs.writeFileSync(path.join(__dirname, '../public/uploads/', e.newFilename), data)
                    obj.url.push(system.url + '/' + file.newFilename)
                })
            }
            if (Object.prototype.toString.call(file) == '[object Object]') {
                let data = fs.readFileSync(file.filepath)
                fs.writeFileSync(path.join(__dirname, '../public/uploads/', file.newFilename), data)
                obj.url = system.url + '/' + file.newFilename
            }
            ctx.body = backData(200, obj)

2、koa下载文件

后端:

第一种:获取需要请求的文件名称,寻找文件路径,通过fs的createReadStream读取文件路径转化成流文件传给前端

            //方式一:fs推流
            let fileName = ctx.request.body.fileName
            ctx.attachment(fileName)//设置名称
            let file = path.join(__dirname, '../public/uploads', fileName);
            ctx.body = fs.createReadStream(file)

第二种:获取需要请求的文件名称,寻找文件,用koa-send把文件发送给前端,失败的话要注意路径是否正确(下面例子中我的目录是/public/uploads,更多参数去看koa-send

            //方式二:koa-send
            //ctx.request.query.fileName  or  ctx.query.fileName
            let fileName = ctx.request.query.fileName
            ctx.attachment(fileName)//设置名称
            await send(ctx, fileName, { root: path.join(__dirname, '../public/uploads') })

前端:

设置axios的responseType属性,以获取blob类型的数据,不然文件会乱码损坏

获取blob数据后,通过window.URL.createObjectURL(blob)读取下载文件的url

再创建的a标签,设置它的href属性为文件下载url,它的download属性为文件名称,a.click触发下载然后再触发remove把自己干掉

最后window.URL.revokeObjectURL(url)回收url

//responseType一定一定要加,加了还是乱码,要注意是不是axios的不同方法的配置位置不对,比如axios.get(url[, config])和axios.post(url[, data[, config]])
    return axios.get(url, {
        headers,
        responseType: 'blob',
    })

然后就是接收

    let url = window.URL.createObjectURL(res.data)
    let a = document.createElement('a')
    a.href = url
    a.download = 'fileName.拓展名'//需要动态的话从res.headers['content-disposition']里获取
    a.click()
    a.remove()
    window.URL.revokeObjectURL(url)

 获取拓展名(从res.headers['content-disposition']里获取)

let download = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(res.headers['content-disposition'])[1].replace(/['"]/g, '')
a.download =download 

 

标签:文件,fs,koa,上传下载,ctx,fileName,url,let,file
From: https://www.cnblogs.com/lovewhatIlove/p/17242606.html

相关文章

  • .gitignore文件
    .gitlogsrebel.xmltarget/!.mvn/wrapper/maven-wrapper.jarlog.path_IS_UNDEFINED.DS_Storeoffline_user.md###STS###.apt_generated.classpath.factorypath.project.settings.springBeans###IntelliJIDEA###.idea*.iws*.iml*.ipr###NetBeans###nbproject/private/b......
  • VBS批量修改文件名
    vbs批量修改文件后缀名源码'批量修改文件后缀名FunctionGetScriptPath()GetScriptPath=Left(WScript.ScriptFullName,Len(WScript.ScriptFullName)-Len(WScript.ScriptName))EndFunctionDimbefore:before=InputBox("请输入要修改的文件后缀名:","用户输入")......
  • 【shell】win10的wsl子系统,删除文件报错-bash: /usr/bin/rm: Argument list too long
    1、场景  由于测试需要删除缓存目录相关文件,但是rm-rf./*的时候报错 2、处理方法cd[需要删除的目录]ls|xargs-n10rm-frls参数解释:输出所有的文件名(用空格分割) xargs就是将ls的输出,每10个为一组(以空格为分隔符),作为rm-rf的参数也就是说将所有文件名10......
  • 【批处理】powershell RMDIR删除文件夹及文件报错,Remove-Item: A positional paramet
    1、场景  由于测试导致的缓存文件较多,需要删除,手动删除太慢,所以直接用命令删除 2、报错备注:没装powershell的电脑可以用的  3、处理方法cmd--%/cRMDIR/Q/SC:\Users\ADMINI~1\AppData\Local\Temp参数解释:--%,停止解析符号,告诉PowerShell停止解析其余参数,并......
  • c++文件操作
    include<iostream>#include<fstream>usingnamespacestd;#include<string>voidtest01(){stringl;ofstreama;a.open("test.txt",ios::out);/*getline(cin,l);*///可以正常写入空格a<<"你好!!!"<......
  • 分玩具的源文件mytool.h
    #include<stdio.h>#include<stdlib.h>#defineSTACK_INT_SIZE10#defineSTACKINCREMENT5#defineOK1#defineERROR0#defineMAXQSIZE51typedefintElemType;typedefintQElemType;/*队列元素类型*///栈的基本操作typedefstruct{ElemType*base;......
  • 如何解决Reporting Services目录数据库文件存在的问题
    如何解决ReportingServices目录数据库文件存在的问题浏览:1686|更新:2022-12-0411:211,自检时提示“ReportingServices目录数据库文件存在”失败,“ReportingServices目录临时数据库文件存在”失败。2,打开SQLServer数据库的安装目录,例如:C:\ProgramFiles(x86)\M......
  • Qt5.9 UI设计(三)——添加UI、类及资源文件
    前言设计一个软件,最简单的方式就是把控件直接往UI上放,然后再把功能实现了。这样可以实现基本的功能,但是界面不能缩放,如果拖动软件改变界面的大小,界面上的控件就会乱成一团,或者是界面的控件压根就不会跟着界面的大小进行改变。要使界面上的所有控件都随着界面的变化而变化,做到自......
  • 无显示器如何通过配置文件快速修复树莓派无法通过 SSH 访问的问题 All In One
    无显示器如何通过配置文件快速修复树莓派无法通过SSH访问的问题AllInOne在没有显示器的情况下如何通过配置系统文件快速的修复树莓派无法通过SSH访问的问题AllInOne无显示器SSH远程访问树莓派不小心或不知道怎么把SSH关闭了,导致无法SSH访问了❌$pingra......
  • Linux设备文件自动生成
    原文:https://www.cnblogs.com/chen-farsight/p/6154941.html第一种是使用mknod手工创建:#mknod<devfilename><devtype><major><minor>第二种是自动创建设备节点:利用udev(mdev)来实现设备文件的自动创建,首先应保证支持udev(mdev),由busybox配置。   具体udev相关知识这里不......