How Egg implements file upload

File uploads are an unavoidable item in development. So when there is no separate resource server, the uploaded files may have to be placed on our project folder server. How do we implement file uploads?

First off, we need a test page. html is used to upload files. as follows:

<!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>

Secondly, we need to install moment mkdirp for time conversion and folder creation

npm i moment mkdirp -S

Next, we have to consider the process of uploading files.

  1. We need to call and select the file on the front end, call the interface and bring the picture.

  2. When the server receives the image information sent, we need to obtain the image content.

  3. Find a directory in the current project and put the pictures in, usually under app/public/upload.

  4. Put the obtained image content into the specified directory.

  5. Returns the address of the uploaded file. Server address + picture name + suffix

We need to determine the receiving method of the file in the server, here we use the file mode. That is, the file receiving mode

Go to config/config.default.js to configure the receiving form of the file

config.multipart = {
    mode: 'file'
}

Among them, there are many multipart configurations, such as the customization of the upload format, the limitation of the file size, and so on.

For details, you can inquire on the official website File upload | Egg

After the configuration is complete. Our development process is as follows:

  • Through the form of ctx.request.files, obtain the file resource of the uploaded file at the front end.
  • Read file content through fs.readFileSync(file.filepath).
  • Then configure the storage location of public resource files globally. Get this location.
// config.default.js
​
const userConfig = {
    // myAppName: 'egg',
    uploadDir: 'app/public/upload',
  };
  • Use this.config.uploadDir to get the location directory
  • Add the file name to this directory to get the final generated path
  • Write the file to the final path
  • Upload was successful.

So our code is as follows:

New 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;

We open the uploaded file html template just started for testing

After selecting the file

 

We use the server address + the image link returned to try to access

 

The visit was successful. The mission is over.

Guess you like

Origin blog.csdn.net/qq_31281245/article/details/127925008