Egg如何实现文件上传

举报
赵小左 发表于 2022/11/30 20:32:08 2022/11/30
【摘要】 ​ 文件上传是开发中不可避免的一项。那么在没有单独的资源服务器的时候,上传的文件可能要放在我们的项目文件夹服务器上,我们如何实现文件上传呢?首先不用想,我们需要一个测试页面。html用来上传文件。如下:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible...

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

首先不用想,我们需要一个测试页面。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模板进行测试

选择文件后

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

编辑

访问成功。任务结束。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。