课程名称:web前端架构师
课程章节:第17周 第二章 文件上传基本原理实现以及使用sharp 完成图片处理
主讲老师:张轩
课程内容:上传文件的过程
上传文件
encType
- application/x-www-form-urlencoded
- multipart/form-data
下面看 form 表单文件上传的例子
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
<p><input type="text" name="text1" value="text default">
<p><input type="file" name="file1">
<p><button type="submit">Submit</button>
</form>
当 enctype 为 application/x-www-form-urlencoded 发送的数据
查看发送的数据,这时发送的内容没有包含上传文件的内容
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
text1=text+default&file1=a.txt
multipart/form-data 发送的数据
POST / HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"
text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain
Content of a.txt.
-----------------------------735323031399963166993862150--
egg.js 的处理方式
- bodyParser 中间件 - - 普通文本 =》 ctx.request.body
- 当请求的 Content-Type 为 application/json,application/json-patch+json,application/vnd.api+json 和 application/csp-report 时,会按照 json 格式对请求 body 进行解析,并限制 body 最大长度为 100kb。
- 当请求的 Content-Type 为 application/x-www-form-urlencoded 时,会按照 form 格式对请求 body 进行解析,并限制 body 最大长度为 100kb。
- egg-multipart 处理二进制文件, egg-multipart 是 egg.js 的内置插件
- 在 koa 中可以使用 koa-multer 处理二进制文件
使用 egg.js 完成文件上传
// config/config.default.js
exports.multipart = {
mode: 'file',
};
public async upload() {
const { ctx } = this;
const files = ctx.request.files;
ctx.body = files;
}
然后我们发送请求,会返回
[
{
"field": "avatar",
"filename": "1666884074121.jpg",
"encoding": "7bit",
"mime": "image/jpeg",
"fieldname": "avatar",
"transferEncoding": "7bit",
"mimeType": "image/jpeg",
"filepath": "/var/folders/m0/fn7968ln6mb1g89x66nxrvch0000gn/T/egg-multipart-tmp/egg-app/2022/11/15/23/6a4a7e32-4b52-4d62-87a3-65d86babdcae.jpg"
}
]
其中 filepath 就是我们上传文件到目录
设置上传文件到保存目录
config.multipart = {
mode: 'file',
tmpdir: path.join(appInfo.baseDir, 'uploads'),
};
这样上传保存文件到功能就完成了
返回上传文件到url
我们可以将上传到文件放到静态文件目录下(也可以将上传文件的目录设置为静态文件),这样就可以将上传的图片就有对应的 url 了
Egg 内置了 static 插件,线上环境建议部署到 CDN,无需该插件
https://www.eggjs.org/zh-CN/intro/quickstart#静态资源
将上传文件保存的目录设置为静态文件目录
config.static = {
dir: [{
prefix: '/public', dir: path.join(appInfo.baseDir, 'app/public'),
}, {
prefix: '/uploads', dir: path.join(appInfo.baseDir, 'uploads'),
}],
};
返回上传图片对应的 url
public async upload() {
const { ctx, app } = this;
const file = ctx.request.files[0];
file.filepath = file.filepath.replace(app.config.baseDir, app.config.baseURL);
ctx.helper.success({ ctx, res: file });
}