美文网首页Web前端之路Nodejs
eggjs结合七牛云对象存储实现文件上传功能

eggjs结合七牛云对象存储实现文件上传功能

作者: webcandy | 来源:发表于2020-03-12 13:25 被阅读0次

    本文首发于 艾特网 - 程序员导航站 中的博客专栏,地址:https://www.iiter.cn/blogs/37
    强烈建议收藏或保存

    说在前面

    最近想着给 艾特网 - 程序员导航站 后台扩展文件上传的功能。因为考虑到七牛云对象存储比较划算,而且每个月会免费赠送 10GB的标准存储空间,基本算是白嫖。所以就打算拿七牛云来练练手。想注册七牛云的同学可以点这里

    image

    安装依赖

    七牛云官网中有 nodejs 版本的 sdk,我们通过 npm 来安装

    npm install qiniu
    

    再安装如下依赖,后面会用到

    npm install await-stream-ready stream-wormhole
    

    创建路由

    router.js 文件中创建上传文件路由,映射 utils 这个 controller 下面的 uploadFiles 方法,这块可根据自己的业务需求自行调整。

    router.post("/upload", controller.utils.uploadFiles);
    

    创建控制器

    打开 utils 文件,创建 uploadFiles 方法,写入如下内容。

    async uploadFiles() {
        const { ctx } = this;
        const data = await ctx.service.utils.uploadFiles();
        if(data){
          ctx.body = data;
        }else{
          ctx.body = {
            message:"上传失败"
          }
        }
      }
    

    创建service

    在 service 中 utils.js 文件里完成上传逻辑

    const Service = require("egg").Service;
    const fs = require("fs");
    const path = require("path");
    const qiniu = require("qiniu");
    const awaitWriteStream = require("await-stream-ready").write;
    const sendToWormhole = require("stream-wormhole");
    const md5 = require("md5");
    const bucket = ""; //要上传的空间名
    const imageUrl = ""; // 空间绑定的域名
    const accessKey = ""; //Access Key
    const secretKey = ""; //Secret Key
    const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
    const options = {
      scope: bucket
    };
    const putPolicy = new qiniu.rs.PutPolicy(options);
    const uploadToken = putPolicy.uploadToken(mac);
    let config = new qiniu.conf.Config();
    config.zone = qiniu.zone.Zone_z0;
    class utilsService extends Service {
      async uploadFiles() {
        const { ctx } = this;
        const stream = await ctx.getFileStream();
        const filename =
          md5(stream.filename) + path.extname(stream.filename).toLocaleLowerCase();
        const localFilePath = path.join(__dirname, "../public/uploads", filename);
        const writeStream = fs.createWriteStream(localFilePath);
        try {
          await awaitWriteStream(stream.pipe(writeStream));
          const formUploader = new qiniu.form_up.FormUploader(config);
          const putExtra = new qiniu.form_up.PutExtra();
          const imgSrc = await new Promise((resolve, reject) => {
            formUploader.putFile(
              uploadToken,
              filename,
              localFilePath,
              putExtra,
              (respErr, respBody, respInfo) => {
                if (respErr) {
                  reject("");
                }
                if (respInfo.statusCode == 200) {
                  resolve(imageUrl + respBody.key);
                } else {
                  reject("");
                }
                // 上传之后删除本地文件
                fs.unlinkSync(localFilePath);
              }
            );
          });
          if (imgSrc !== "") {
            return {
              url: imgSrc
            };
          } else {
            return false;
          }
        } catch (err) {
          //如果出现错误,关闭管道
          await sendToWormhole(stream);
          return false;
        }
      }
    }
    module.exports = utilsService;
    

    注意:

    1. 代码中这一行的Zone_z0应该和自己空间的存储区域相对应,不然会报错,比方说自己空间是华北区的,对应的就是Zone_z1
    config.zone = qiniu.zone.Zone_z0;
    
    image
    1. Access Key 和 Secret Key 可以在这里查看
      https://portal.qiniu.com/user/key

    上传测试

    这里用的是 postman 测试
    Headers

    {
      "Content-Type":"multipart/form-data"
    }
    

    Body选择form-data类型
    创建一个key为file,右下角类型选择File类型,然后在value属性中选择一张图片。

    image

    点击蓝色的Send按钮即可上传

    至此,一个完整的 eggjs 结合七牛云对象存储的文件上传案例就完成啦。

    本文参考如下文章:
    egg.js 上传文件
    NodeJS + 七牛云实现图片上传

    相关文章

      网友评论

        本文标题:eggjs结合七牛云对象存储实现文件上传功能

        本文链接:https://www.haomeiwen.com/subject/qwsujhtx.html