eggjs結合七牛雲對象存儲實現文件上傳功能

本文首發於艾特網 - 程序員導航站 中的博客專欄,地址:https://www.iiter.cn/blogs/37 建議收藏或保存

說在前面

最近想着給 艾特網 - 程序員導航站 後臺擴展文件上傳的功能。因爲考慮到七牛雲對象存儲比較划算,而且每個月會免費贈送 10GB的標準存儲空間,基本算是白嫖。所以就打算拿七牛雲來練練手。想註冊七牛雲的同學可以點這裏

安裝依賴

七牛雲官網中有 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;

  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屬性中選擇一張圖片。

點擊藍色的Send按鈕即可上傳

至此,一個完整的 eggjs 結合七牛雲存儲的文件上傳就完成啦。

本文參考如下文章:
egg.js 上傳文件
NodeJS + 七牛雲實現圖片上傳

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章