文件上传是开发中不可避免的一项。那么在没有单独的资源服务器的时候,上传的文件可能要放在我们的项目文件夹服务器上,我们如何实现文件上传呢?
首先不用想,我们需要一个测试页面。html用来上传文件。如下:
- 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>图片上传title>
- head>
- <body>
- <input type="file" id='upload' />
- <script>
- // 获取 input 标签的 dom
- var input = document.getElementById('upload')
- // 监听它的变化
- input.addEventListener('change', function(e) {
- // 获取到上传的 file 对象
- var file = input.files[0]
- // 声明 FormData 实例 formData
- let formData = new FormData()
- // 添加实例属性 file
- formData.append('file', file)
- console.log('formData', formData)
- // 调用服务端上传接口。
- fetch('http://localhost:7001/api/upload', {
- method: 'POST',
- body: formData
- }).then(res => {
- if(res.ok) {
- console.log('success')
- return res.json();
- } else {
- console.log('error')
- }
- }).then(res => {
- console.log('res is', res);
- })
- })
- script>
- body>
- html>
其次我们需要安装 moment mkdirp 用来实现时间转换以及文件夹创建
npm i moment mkdirp -S
下来,我们就必须要考虑下上传文件的流程。
我们需要在前端调选择文件,调用接口并且将图片带上。
在服务端接收到发来的图片信息的时候,我们需要获取到图片内容。
在当前项目找个目录将图片放进去,一般都会放在 app/public/upload 下。
将获取到的图片内容放入到指定的目录下。
返回上传文件的地址。服务器地址 + 图片名称 + 后缀
我们需要在服务端中确定文件的接收方式,这里我们采用file 模式。也就是文件接收模式
前往config/config.default.js 配置文件的接收形式
- config.multipart = {
- mode: 'file'
- }
其中 multipart 的配置有许多,如 上传格式的定制,文件大小的限制等。
详细的,大家可以在官网进行查询 文件上传 | Egg
配置完成后。我们的开发流程如下:
- // config.default.js
-
- const userConfig = {
- // myAppName: 'egg',
- uploadDir: 'app/public/upload',
- };
所以我们的代码就如下:
新建controller/ upload.js
- const fs = require('fs') // 引入fs,node 自带的文件处理工具
- const moment = require('moment') // 引入moment 时间处理工具
- const mkdirp = require('mkdirp') // 引入文件夹处理工具
- const path = require('path') // 引入路径处理工具
-
- const Controller = require('egg').Controller;
-
- class UploadController extends Controller {
- async upload() {
- const { ctx } = this
- // 1 获取我们上传文件。 是一个数组,只有一个文件情况下,默认为数组中的下标0。
- let file = ctx.request.files[0]
-
- // 2 声明存放资源的路径
- let uploadDir = ''
-
- try {
- // 3 读取文件内容
- let f = fs.readFileSync(file.filepath)
- // 4 获取当前日期
- let day = moment(new Date()).format('YYYYMMDD')
- // 5 生成文件最后要保存的路径地址
- let dir = path.join(this.config.uploadDir, day);
-
- await mkdirp(dir); // 6 这个方法是,如果 上述dir 路径存在,那就不创建,如果不存在则会创建这个对应目录文件夹
- // 7 返回图片保存的完整路径
- uploadDir = path.join(dir,file.filename);
- // 8 将图片内容写入到文件夹下
- fs.writeFileSync(uploadDir, f)
- } finally {
- // 清除临时文件
- ctx.cleanupRequestFiles();
- }
-
- ctx.body = {
- code: 200,
- msg: '上传成功',
- data: uploadDir.replace(/app/, ''),// 删除 /app/ 这个目录
- }
- }
- }
-
- module.exports = UploadController;
我们打开刚开始的上传文件html模板进行测试
选择文件后

我们使用服务器地址+ 返回的图片链接尝试访问

访问成功。任务结束。