Egg如何实现文件上传

文件上传是开发中不可避免的一项。那么在没有单独的资源服务器的时候,上传的文件可能要放在我们的项目文件夹服务器上,我们如何实现文件上传呢?

首先不用想,我们需要一个测试页面。html用来上传文件。如下:

<!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>图片上传</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

下来,我们就必须要考虑下上传文件的流程。

  1. 我们需要在前端调选择文件,调用接口并且将图片带上。

  2. 在服务端接收到发来的图片信息的时候,我们需要获取到图片内容。

  3. 在当前项目找个目录将图片放进去,一般都会放在 app/public/upload 下。

  4. 将获取到的图片内容放入到指定的目录下。

  5. 返回上传文件的地址。服务器地址 + 图片名称 + 后缀

我们需要在服务端中确定文件的接收方式,这里我们采用file 模式。也就是文件接收模式

前往config/config.default.js 配置文件的接收形式

config.multipart = {
    mode: 'file'
}

其中 multipart 的配置有许多,如 上传格式的定制,文件大小的限制等。

详细的,大家可以在官网进行查询 文件上传 | Egg

配置完成后。我们的开发流程如下:

  • 通过ctx.request.files的形式,获取到前端上传文件的文件资源。
  • 通过fs.readFileSync(file.filepath) 来读取文件内容。
  • 然后在全局配置公共资源文件存放位置。获取这个位置。
// config.default.js
​
const userConfig = {
    // myAppName: 'egg',
    uploadDir: 'app/public/upload',
  };
  • 使用 this.config.uploadDir 获取位置目录
  • 将文件名加入到这个目录下获取最终生成的路径
  • 将文件写入到最终路径下
  • 上传成功。

所以我们的代码就如下:

新建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模板进行测试

选择文件后

 

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

 

访问成功。任务结束。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵小左

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值