-
Notifications
You must be signed in to change notification settings - Fork 509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Node.js 应用:Koa2 之文件上传下载 #25
Labels
Comments
线上博客用的是hexo theme还是自己写的 |
@julyL 基于 hexo 的 Next 主题改的 |
@lin-xin |
router.post('/upload', async (ctx){
const file = ctx.request.body.files.file; // 获取上传文件
return ctx.body = file.path; // upload/xxx.xx
})
# 上面代码中ctx.request.body是空对象,文件信息还是放在ctx.request.files.file里
router.post('/upload', async (ctx){
const file = ctx.request.files.file; // 获取上传文件
return ctx.body = file.path; // upload/xxx.xx
})
|
还是直接location.href=path粗暴直接。。 |
ctx.request里没files |
需要安装 koa-body 之类的中间件 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
前言
上传下载在 web 应用中还是比较常见的,无论是图片还是其他文件等。在 Koa 中,有很多中间件可以帮助我们快速的实现功能。
文件上传
在前端中上传文件,我们都是通过表单来上传,而上传的文件,在服务器端并不能像普通参数一样通过
ctx.request.body
获取。我们可以用koa-body
中间件来处理文件上传,它可以将请求体拼到ctx.request
中。使用中间件后,就可以在
ctx.request.body.files
中获取上传的文件内容。需要注意的就是设置 maxFileSize,不然上传文件一超过默认限制就会报错。接收到文件之后,我们需要把文件保存到目录中,返回一个 url 给前端。在 node 中的流程为
const reader = fs.createReadStream(file.path)
const writer = fs.createWriteStream('upload/newpath.txt')
reader.pipe(writer)
koa-body 是将上传的文件放到了系统的临时文件里,然后我们再从临时文件里读取到 upload/ 目录下。其实 koa-body 还可以通过 formidable.uploadDir 属性直接设置存储目录
然后就可以通过 ctx.request.body.files.file 直接获得到上传的文件了。
文件下载
koa-send
是一个静态文件服务的中间件,可用来实现文件下载功能。在前端进行下载,有两个方法:
window.open
和表单提交。这里使用简单一点的window.open
。这里
window.open
默认是开启一个新的窗口,一闪然后关闭,给用户的体验并不好,可以加上第二个参数window.open('/download/1.png', '_self');
,这样就会在当前窗口直接下载了。然而这样是将 url 替换当前的页面,则会触发beforeunload
等页面事件,如果你的页面监听了该事件做一些操作的话,那就有影响了。那么还可以使用一个隐藏的 iframe 窗口来达到同样的效果。批量下载
批量下载和单个下载也没什么区别嘛,就多执行几次下载而已嘛。这样也确实没什么问题。如果把这么多个文件打包成一个压缩包,再只下载这个压缩包,是不是体验起来就好一点了呢。
文件打包
archiver
是一个在 Node.js 中能跨平台实现打包功能的模块,支持 zip 和 tar 格式。如果直接打包整个文件夹,则不需要去遍历每个文件 append 到压缩包里
中文编码问题
当文件名含有中文的时候,可能会出现一些预想不到的情况。所以上传时,含有中文的话我会对文件名进行
encodeURI()
编码进行保存,下载的时候再进行decodeURI()
解密。ctx.attachment
将 Content-Disposition 设置为 “附件” 以指示客户端提示下载。通过解码后的文件名作为下载文件的名字进行下载,这样下载到本地,显示的还是中文名。然鹅,
koa-send
的源码中,会对文件路径进行decodeURIComponent()
解码:这时解码后去下载含中文的路径,而我们服务器中存放的是编码后的路径,自然就找不到对应的文件了。
要想解决这个问题,那么就别让它去解码。不想动
koa-send
源码的话,可使用另一个中间件koa-sendfile
代替它。The text was updated successfully, but these errors were encountered: