egg.js上傳圖片到本地與上傳到七牛云對象存儲

1.html方式上傳

<form action="/back/banner/upload?_csrf=<%=csrf%>" method="POST" enctype="multipart/form-data">
    廣告標題:<input type="text" name="title" />
    鏈接地址:<input type="text" name="link"/>
    類型:<select name="type">
            <option value="0">PC</option>
            <option value="1">APP</option>
            <option value="2">H5</option>
          </select>
    上傳圖片:<input type="file" id="file" name="img_url" />
    <input type="submit" class="btn_yes"  value="提交">
</form>


2.ajax方式上傳

<div class="uploadBody">
    廣告標題:<input type="text" name="title" />
    鏈接地址:<input type="text" name="link"/>
    類型:<select name="type">
            <option value="0">PC</option>
            <option value="1">APP</option>
            <option value="2">H5</option>
            </select>
    上傳圖片:<input type="file" id="file" name="img_url" />
            <button class="btn_yes" type="submit">提交</button>
</div>
<script src="js/jquery-1.11.0.min.js"></script>
<script>
$(function () {
    $('.btn_yes').click(function(event){
        var formData = new FormData();
        formData.append('title', $("input[name='title']").val());
        formData.append('type', $("select[name='type']").val());
        formData.append('link', $("input[name='link']").val());
        formData.append('img_url', $("input[type=file]")[0].files[0]);
        
        $.ajax({
            url: '/back/banner/upload?_csrf=<%-csrf%>',
            type: 'post',
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            success: function (req) {
                console.log(req);
            },
            error: function (err) {
                console.log(err.statusText);
                return false;
            }
        });
    })
});
</script>

3.egg.js后端上傳圖片保存到本地

(1)安裝依賴包
  • 安裝mz-modules包
    cnpm install mz-modules --save
  • 安裝時間格式化插件
    cnpm i silly-datetime --save
(2)schema
module.exports = app => {
  const mongoose = app.mongoose;
  const Schema = mongoose.Schema;
  const BannerSchema = new Schema({
    title: { type: String },
    type: {
      type: Number,
      default: 0  //0:PC;1:APP;2:H5
    },
    img_url: { type: String },
    link: { type: String },
    status: { type: Number, default: 1 },
    create_time: { type: Date, default: Date.now },
    update_time: { type: Date, default: null }
  });
  return mongoose.model('Banner', BannerSchema, 'banner');
};
(3)service\utils
const path = require("path");
const mkdirp = require('mz-modules/mkdirp');
const sd = require('silly-datetime');
const Service = require("egg").Service;

class UtilsService extends Service {
    async getUploadFile(filename){
        let date = sd.format(new Date(),'YYYYMMDD');
        let dir = path.join('app/public/back/upload', date);
        await mkdirp(dir); //創(chuàng)建以日期格式的文件夾
        let timestamp = new Date().getTime();
        let uploadDir = path.join(dir,timestamp + path.extname(filename));
        return {
            uploadDir: uploadDir,
            saveDir: uploadDir.slice(3).replace(/\\/g,'/')
        }
    }
}
module.exports = UtilsService;
(4)Controller 控制層
'use strict';
const fs = require('fs');
const pump = require('mz-modules/pump');
const Controller = require('egg').Controller;

class BannerController extends Controller {
  async upload() {
    const { ctx } = this;
    let files = {};
    let stream;
    let parts = ctx.multipart({ autoFields: true });
    while((stream = await parts()) != null){
        if (!stream.filename){  //圖片名稱  xxx.png
            break;
        }
        let filedname = stream.fieldname;  //字段名稱 img_url
        let dir = await ctx.service.tools.getUploadFile(stream.filename);
        let target = dir.uploadDir;
        let writeStream = fs.createWriteStream(target);
        await pump(stream, writeStream);
        files = Object.assign(files, {[filedname]: dir.saveDir});
    }
    var obj = Object.assign(files, parts.field);
    //console.log(JSON.stringify(obj));
    var result = await ctx.service.back.banner.upload(obj);
    if(result){
        ctx.helper.success({ctx, code:0});
    }else{
        ctx.helper.fail({ctx, code:1, res:result });
    }
  }
}
module.exports = BannerController;
(5)Service 服務(wù)層
const Service = require('egg').Service;
const mongoose = require('mongoose');

class BannerService extends Service {
  async upload(obj) {
    const {ctx} = this;
    return await new ctx.model.Banner(obj).save();
  }
}

module.exports = BannerService;

4.egg.js后端上傳圖片到七牛云對象存儲

(1)安裝依賴包
  • 安裝mz-modules包
    cnpm install mz-modules --save

  • 安裝時間格式化插件
    cnpm i silly-datetime --save

  • 安裝七牛云對象存儲node.js包
    cnpm install qiniu --save

  • 安裝stream-wormhole包
    cnpm install stream-wormhole --save

(2)配置config.default.js
  config.qiniu = {
    accessKey: ' ', //Access Key
    secretKey: ' ', //Secret Key
    bucket: ' ', //要上傳的空間名
    domainName: ' ' //空間綁定的域名
  }
image.png
(3)schema
module.exports = app => {
  const mongoose = app.mongoose;
  const Schema = mongoose.Schema;
  const BannerSchema = new Schema({
    title: { type: String },
    type: {
      type: Number,
      default: 0  //0:PC;1:APP;2:H5
    },
    img_url: { type: String },
    link: { type: String },
    status: { type: Number, default: 1 },
    create_time: { type: Date, default: Date.now },
    update_time: { type: Date, default: null }
  });
  return mongoose.model('Banner', BannerSchema, 'banner');
};
(4)service\utils
const path = require("path");
const mkdirp = require('mz-modules/mkdirp');
const sd = require('silly-datetime');
//qiniu
const fs = require("fs");
const qiniu = require("qiniu");
const sendToWormhole = require("stream-wormhole");
const Service = require("egg").Service;

class UtilsService extends Service {
    async getUploadFile(filename){
        let date = sd.format(new Date(),'YYYYMMDD');
        let dir = path.join('app/public/back/upload', date);
        await mkdirp(dir); //創(chuàng)建以日期格式的文件夾
        let timestamp = new Date().getTime();
        let uploadDir = path.join(dir,timestamp + path.extname(filename));
        return {
            uploadDir: uploadDir,
            saveDir: uploadDir.slice(3).replace(/\\/g,'/')
        }
    }

  async uploadQiNiu(stream, filename, localFilePath) {
    const { ctx } = this;
    const mac = new qiniu.auth.digest.Mac(this.config.qiniu.accessKey, this.config.qiniu.secretKey);
    const options = { scope: this.config.qiniu.bucket };
    const putPolicy = new qiniu.rs.PutPolicy(options);
    const uploadToken = putPolicy.uploadToken(mac);
    let config = new qiniu.conf.Config();
    config.zone = qiniu.zone.Zone_z2;

    try {
        const formUploader = new qiniu.form_up.FormUploader(config);
        const putExtra = new qiniu.form_up.PutExtra();
        const imgUrl = await new Promise((resolve, reject) => {
        formUploader.putFile(uploadToken, filename, localFilePath, putExtra, (respErr, respBody, respInfo) => {
            if (respErr) {
                    reject("上傳失敗");
            }
            if (respInfo.statusCode == 200) {
                    resolve(this.config.qiniu.domainName + "/" + respBody.key);
            } else {
                    reject("上傳失敗");
            }
            // 上傳之后刪除本地文件
            fs.unlinkSync(localFilePath);
          });
        });
        if (imgUrl !== "") {
                return { url: imgUrl };
        } else {
                return false;
        }
    } catch (err) {
        //如果出現(xiàn)錯誤,關(guān)閉管道
        await sendToWormhole(stream);
        return false;
    }
    }
}
module.exports = UtilsService;
(5)helper.js
module.exports = {
    errorCode: {
        0: '成功',
        1: '失敗',
    },
    success: ({ ctx, code=0, res = null }) => {
        ctx.status = 200
        ctx.body = {
          code: code,
          message: ctx.helper.errorCode[code],
          data: res
        }
    },
    fail: ({ ctx, code = 1, res=null }) => {
        ctx.status = 200
        ctx.body = {
          code: code,
          message: ctx.helper.errorCode[code],
          data: res
        }
    }
}
(6)Controller 控制層
'use strict';
const fs = require('fs');
const pump = require('mz-modules/pump');
const path = require("path");
const Controller = require('egg').Controller;

class BannerController extends Controller {
   async upload() {
    const { ctx } = this;
    let stream;
    let files = {};
    let parts = ctx.multipart({ autoFields: true });
    while((stream = await parts()) != null) {
      if (!stream.filename) { //圖片名稱  xxx.png
        break;
      }
      let filedname = stream.fieldname;  //字段名稱 img_url
      let dir = await ctx.service.tools.getUploadFile(stream.filename);
      let filename = dir.filename;
      let localFilePath = path.join(__dirname, "../../" + dir.saveDir);
      //console.log("dirname:" + __dirname); //H:\vuejs\example\xiaomi\app\controller\back
      let writeStream = fs.createWriteStream(localFilePath);
      // 上傳到本地
      await pump(stream, writeStream); 
      // 上傳七牛云對象存儲
      let qiniu = await ctx.service.utils.uploadQiNiu(stream, filename, localFilePath);
      if(qiniu) {
        files = Object.assign(files, {[filedname]: qiniu.url});
      }else{
        ctx.helper.fail({ctx, code:1});
      }
    }
    var obj = Object.assign(files, parts.field);
    var result = await ctx.service.back.banner.upload(obj);
    if(result){
      ctx.helper.success({ctx, code:0});
    }else{
      ctx.helper.fail({ctx, code:1, res:result });
    }
  }
}
module.exports = BannerController;
(7)Service 服務(wù)層
const Service = require('egg').Service;
const mongoose = require('mongoose');

class BannerService extends Service {
  async upload(obj) {
    const {ctx} = this;
    return await new ctx.model.Banner(obj).save();
  }
}

module.exports = BannerService;

5.七牛云對象存儲 新建存儲空間

空間管理/新建空間

image.png

6.七牛云對象存儲創(chuàng)建域名和配置域名的 CNAME

(1)創(chuàng)建域名

域名管理/創(chuàng)建域名

image.png

(2)配置域名的 CNAME
  • 復(fù)制CNAME cdn-dengwq-com-idvc8ce.qiniudns.com 到阿里云的云解析DNS

    image.png

  • 阿里云域名解析

云解析DNS/域名解析/解析設(shè)置

image.png
  • 配置成功


    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容