前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Egg中上传单文件与多文件

Egg中上传单文件与多文件

作者头像
越陌度阡
发布2020-11-26 10:46:34
1.6K0
发布2020-11-26 10:46:34
举报

1. 单文件上传

1. 模板文件

代码语言:javascript
复制
<!-- csrf为egg所提供的安全机制,需要在模板文件上绑定-->
<form action="/admin/upload/singleUpload?_csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
    <ul>
        <li>
            图片名称:<input type="text" name="title" style="width:300px;"/>
        </li>

        <li>
            图片描述:<textarea name="description" id="" cols="60" rows="8" style="width:300px;"></textarea>
        </li>

        <!-- 上传文件必须在所有其他的 fields 后面,否则在拿到文件流时可能还获取不到 fields -->
        <li>
            图片封面:<input type="file" name="cover" style="width:300px;height:26px"/>
        </li>

        <li>
            <button type="submit" class="btn btn-primary">提交</button>
        </li>
    </ul>
</form>

2. 路由

代码语言:javascript
复制
// router.js
'use strict';
module.exports = app => {
    const { router, controller } = app;
    router.post('/admin/upload/singleUpload',controller.admin.upload.singleUpload);
};

3. 控制器

代码语言:javascript
复制
// app/controller/admin/upload.js

'use strict';

// npm install mz-modules --save
// 此模块解决上传超时卡死
// https://github.com/node-modules/mz-modules

const Pump = require('mz-modules/pump');

const Path = require('path');
const Fs = require('fs');

const Controller = require('egg').Controller;
// 上传控制器
class UploadController extends Controller {

    // 单文件上传
    async singleUpload() {
        // 获取表单提交的数据
        let stream = await this.ctx.getFileStream();
        // 防止上传空文件
        if (!stream.filename) {
            return;
        }
        // 文件名,实际项目中文件名要添加时间戳
        let filename = stream.filename.toLowerCase();

        // 上传的目录,注意upload目录要存在,实际项目中以云服务器地址为准,入库要替换地址符号
        let target = 'app/public/admin/upload/' + Path.basename(filename)
        // 创建写入流
        let writeStream = Fs.createWriteStream(target);

        // 上传超过时长会卡死
        // stream.pipe(writeStream);

        // 上传超过时长不会卡死
        await Pump(stream, writeStream);
        // 返回上传的信息
        this.ctx.body = {
            // 表单上传的图片
            url: target,
            // 表单的其它数据
            fields: stream.fields
        }
    }
   
    
}

module.exports = UploadController;

2. 多文件上传

1. 模板文件

代码语言:javascript
复制
<!-- csrf为egg所提供的安全机制,需要在模板文件上绑定-->
<form action="/admin/upload/multiUpload?_csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
    <ul>
        <input type="hidden" name="_csrf" value="<%=csrf%>">
        <li> 
            图片名称:<input type="text" name="title" style="width:300px;"/>
        </li>
        <li>
            图片描述:<textarea name="description" id="" cols="60" rows="8" style="width:300px;"></textarea>
        </li>
        <!-- 上传文件必须在所有其他的 fields 后面,否则在拿到文件流时可能还获取不到 fields -->
        <li>
            用户头像:<input type="file" name="avatar" style="width:300px;height:26px"/>
        </li>
        <li>
            素材封面:<input type="file" name="cover" style="width:300px;height:26px"/>
        </li>

        <li>
            <button type="submit" class="btn btn-primary">提交</button>
        </li>
    </ul>
</form>

2. 路由

代码语言:javascript
复制
// router.js
'use strict';
module.exports = app => {
    const { router, controller } = app;
    router.post('/admin/upload/multiUpload',controller.admin.upload.multiUpload);

};

3. 控制器

代码语言:javascript
复制
// app/controller/admin/upload.js

'use strict';

// npm install mz-modules --save
// 此模块解决上传超时卡死
// https://github.com/node-modules/mz-modules
const Pump = require('mz-modules/pump');

const Path = require('path');
const Fs = require('fs');

const Controller = require('egg').Controller;
// 上传控制器
class UploadController extends Controller {

    // 多文件上传
    async multiUpload() {
        // autoFields: true 表示除了文件的其它字段
        let parts = this.ctx.multipart({ autoFields: true });
        let files = [];
        let stream;
        // 循环获取数据流
        while ((stream = await parts()) != null) {
            if (!stream.filename) {
                // 多文件上传时,只能break,不能return
                break;
            }
            // 文件名,实际项目中文件名要添加时间戳
            let filename = stream.filename.toLowerCase();
            // 文件表单的name
            let fieldname = stream.fieldname;
            // 上传的目录,注意upload目录要存在,实际项目中以云服务器地址为准,入库要替换地址符号
            let target = 'app/public/admin/upload/' + Path.basename(filename);

            let writeStream = Fs.createWriteStream(target);
            await Pump(stream, writeStream);

            files.push({
                [fieldname]: target
            });
        }
        // 返回上传的信息
        this.ctx.body = {
            // 表单上传的文件
            files: files,
            // 表单的其它数据,注意放到循环后面,否则拿不到对应的字段
            fields: parts.field
        }

    }
}

module.exports = UploadController;

3. 上传配置

代码语言:javascript
复制
// config/config.default.js

'use strict';
module.exports = appInfo => {
    const config = exports = {};
    config.keys = appInfo.name + '_1585450669767_9677';

    // 上传文件的配置
    // https://github.com/eggjs/egg-multipart
    config.multipart = {
        // 只允许上传的图片格式
        whitelist:['.png','.jpg','.jpeg'],
        // 文件允许大小
        fileSize: '50mb', 
    }

    // 配置两种模板引擎
    config.view = {
        mapping: {
            '.html': 'ejs',
            '.nj': 'nunjucks'
        }
    }

    return config

};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 单文件上传
  • 2. 多文件上传
  • 3. 上传配置
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档