一文搞懂eggjs中上傳文件

1、基本的配置

eggjs中上傳文件的官方文檔html

  • 一、配置上傳的路由git

    module.exports = (app) => {
      const { router, controller } = app;
      router.resources('file', '/api/v1/file', controller.file);
    };
    複製代碼
  • 二、在config/config.default.js中配置上傳的基本配置(能夠參考官方文檔)github

    ...
    // 配置上傳
    config.multipart = {
      fileSize: '50mb',
      mode: 'stream',
      fileExtensions: ['.xls', '.txt'], // 擴展幾種上傳的文件格式
    };
    ...
    複製代碼
  • 三、安裝幾個基本的包ajax

    npm install await-stream-ready stream-wormhole dayjs
    複製代碼

2、使用form表單上傳

  • 一、模板的代碼shell

    <form method="POST" action="/api/v1/file" enctype="multipart/form-data">
      title: <input name="title" /> file: <input name="file" type="file" />
      <button type="submit">Upload</button>
    </form>
    複製代碼
  • 二、在控制器中使用fs及數據流寫入文件(在控制器層)
async create() {
  // 獲取文件流
  const stream = await this.ctx.getFileStream();
  // 定義文件名
  const filename = Date.now() + path.extname(stream.filename).toLocaleLowerCase();
  // 目標文件
  const target = path.join('app/public/uploads', filename);
  //
  const writeStream = fs.createWriteStream(target);
  console.log('-----------獲取表單中其它數據 start--------------');
  console.log(stream.fields);
  console.log('-----------獲取表單中其它數據 end--------------');
  try {
    //異步把文件流 寫入
    await awaitWriteStream(stream.pipe(writeStream));
  } catch (err) {
    //若是出現錯誤,關閉管道
    await sendToWormhole(stream);
    // 自定義方法
    this.error(err);
  }
  // 自定義方法
  this.success({ url: '/public/uploads/' + filename });
}
複製代碼
  • 三、能夠將生成的url地址傳遞服務層,存到數據庫中

3、使用ajax上傳文件

  • 一、基本的html頁面數據庫

    <h1>ajax提交</h1>
    <input type="text" id="username" />
    <input name="file" type="file" id="file" />
    <button id="btn">提交</button>
    複製代碼
  • 二、jqajaxnpm

    <script>
      $('#btn').on('click', function() {
        console.log('提交按鈕');
        let formData = new FormData();
        formData.append('title', $('#username').val());
        formData.append('image', $('#file')[0].files[0]);
        console.log(formData);
        $.ajax({
          url: '/api/v1/file',
          data: formData,
          method: 'post',
          contentType: false,
          processData: false,
          success: function(result) {
            console.log(result);
          },
        });
      });
    </script>
    複製代碼

4、對上傳的文件根據時間分類歸檔

  • 一、修改上傳代碼的控制器api

    const fs = require('fs');
    const path = require('path');
    //故名思意 異步二進制 寫入流
    const awaitWriteStream = require('await-stream-ready').write;
    //管道讀入一個蟲洞。
    const sendToWormhole = require('stream-wormhole');
    const dayjs = require('dayjs');
    
    async create() {
      const stream = await this.ctx.getFileStream();
      console.log('-----------獲取數據 start--------------');
      console.log(stream.fields);
      console.log('-----------獲取數據 end--------------');
      // 基礎的目錄
      const uplaodBasePath = 'app/public/uploads';
      // 生成文件名
      const filename = `${Date.now()}${Number.parseInt( Math.random() * 1000, )}${path.extname(stream.filename).toLocaleLowerCase()}`;
      // 生成文件夾
      const dirname = dayjs(Date.now()).format('YYYY/MM/DD');
      function mkdirsSync(dirname) {
        if (fs.existsSync(dirname)) {
          return true;
        } else {
          if (mkdirsSync(path.dirname(dirname))) {
            fs.mkdirSync(dirname);
            return true;
          }
        }
      }
      mkdirsSync(path.join(uplaodBasePath, dirname));
      // 生成寫入路徑
      const target = path.join(uplaodBasePath, dirname, filename);
      // 寫入流
      const writeStream = fs.createWriteStream(target);
      try {
        //異步把文件流 寫入
        await awaitWriteStream(stream.pipe(writeStream));
      } catch (err) {
        //若是出現錯誤,關閉管道
        await sendToWormhole(stream);
        this.error();
      }
      this.success({ url: path.join('/public/uploads', dirname, filename) });
    }
    複製代碼
  • 二、其它的都不變app

  • 三、上傳生成的目錄dom

    2019
    └── 06
        └── 21
            ├── 1561097630832563.png
            └── 1561097675536863.jpeg
    複製代碼

5、提取到基類的控制器中而且進行傳遞參數分類

  • 一、在基類的控制器中

    const { Controller } = require('egg');
    const fs = require('fs');
    const path = require('path');
    //故名思意 異步二進制 寫入流
    const awaitWriteStream = require('await-stream-ready').write;
    //管道讀入一個蟲洞。
    const sendToWormhole = require('stream-wormhole');
    const dayjs = require('dayjs');
    
    class BaseController extends Controller {
      // 上傳文件的通用方法
      async uploadFile(category = '') {
        const stream = await this.ctx.getFileStream();
        // 基礎的目錄
        const uplaodBasePath = 'app/public/uploads';
        // 生成文件名
        const filename = `${Date.now()}${Number.parseInt( Math.random() * 1000, )}${path.extname(stream.filename).toLocaleLowerCase()}`;
        // 生成文件夾
        const dirname = dayjs(Date.now()).format('YYYY/MM/DD');
        function mkdirsSync(dirname) {
          if (fs.existsSync(dirname)) {
            return true;
          } else {
            if (mkdirsSync(path.dirname(dirname))) {
              fs.mkdirSync(dirname);
              return true;
            }
          }
        }
        mkdirsSync(path.join(uplaodBasePath, category, dirname));
        // 生成寫入路徑
        const target = path.join(uplaodBasePath, category, dirname, filename);
        // 寫入流
        const writeStream = fs.createWriteStream(target);
        try {
          //異步把文件流 寫入
          await awaitWriteStream(stream.pipe(writeStream));
        } catch (err) {
          //若是出現錯誤,關閉管道
          await sendToWormhole(stream);
          return {
            error: '錯誤',
          };
        }
        return {
          url: path.join('/public/uploads', category, dirname, filename),
          fields: stream.fields,
        };
      }
    }
    module.exports = BaseController;
    複製代碼
  • 二、在上傳文件的控制器中使用

    const Controller = require('./../core/base_controller');
    class FileController extends Controller {
      async create() {
        // 上傳頭像的,會在uploads文件夾下有個avatar的文件夾下面纔是201九、0六、21
        const { url, fields } = await this.uploadFile('avatar');
        const result = await 服務層;
        this.success(url);
      }
    }
    複製代碼
  • 三、其它的都不變
相關文章
相關標籤/搜索