node實現圖片上傳功能


方式一

以流的形式上傳圖片直接返回路徑,這樣寫:
好處:方便處理存取數據返回路徑
不好的地方:可能冗余,上傳的文件后面並未使用

1.用koa-body中間件

注:如果已經使用了koa-bodyParser中間件,請remove此中間件,koa-body可以代替koa-bodyParser

在app.js中使用該中間件
const koaBody = require('koa-body')
app.use(koaBody({
  multipart: true
}));
注:由於圖片上傳文本類型為:multipart/form-data,所以需加上此條件

2.前端代碼調用

注:我用的vue+antd vue寫的前端,其余框架同理

3.后端node實現

(1).在/controllers/upload.js中寫入
var upload_img = async (ctx, next) => {
  // 上傳單個文件
  console.log(ctx.request.files.uploadImg, '==========================')
  const file = ctx.request.files.uploadImg // 獲取上傳文件
  // 創建可讀流
  const reader = fs.createReadStream(file.path);
  let name=stringRandom(16, { numbers: true })+'.png';
  let filePath = path.join(__dirname, '../public/upload/') + name;
  // 創建可寫流
  const upStream = fs.createWriteStream(filePath);
  // 可讀流通過管道寫入可寫流
  reader.pipe(upStream);
  return ctx.body = {
    code:200, 
    data:{
      path:`/upload/${name}`,
      name:file.name
    },
    message:"上傳成功!"
  } ;
};
(2)在app.js中寫入:
const path = require('path');
const static = require('koa-static');//配置靜態資源
//設置靜態資源路徑
app.use(static(
  path.join(__dirname, 'public'),{    //靜態文件所在目錄
      maxage: 30*24*60*60*1000        //指定靜態資源在瀏覽器中的緩存時間
  }
));
注:(1)ctx.request.files.uploadImg,由於前端的upload組件name為uploadImg,所以這里寫uploadImg
(2)寫入靜態資源讀取,便於前端訪問該圖片
(3)該方法的本質:獲取圖片上傳者圖片在他電腦位置,把這張圖片通過管道存入我們指定的自己的服務器上

方式二

為了不造成服務器圖片冗余,減少無需圖片上傳,實現:
1.前端每次上傳生成base64圖片(可預覽)
2.當整個表單提交之后再把這個圖片的base64提交給后台
3.后台接受base64圖片,通過buffer轉為圖片格式,用stringRandom生成隨機數為圖片名字存儲到服務器。

1.前端每次上傳生成base64圖片

前端代碼:
<template>
<div>
  <h4>上傳base64圖片</h4>
  <input type="file" @change="Preview($event)" accept="image/*" ref="showinput">
  <div>圖片名字:{{imgName}}</div>
  <img :src="imgData" alt="">
  <a-button  type="primary" @click="handleSubmit">上傳</a-button>

</div>
</template>

<script>
import {SubmitBaseImg} from '../assets/js/getData'
export default {
  data (){
    return {
      imgName:'',
      imgData:'',
    };
  },
  methods:{
    Preview(ev){
        // const self=this;
        const file=ev.target.files[0];
        this.imgName=file.name;
        console.log('圖片文件',ev.target.files);
        this.imgObj=ev.target.files[0];
        let obj=new FileReader();
        obj.readAsDataURL(file);
        // obj.onload=function(){
        //   self.img=obj.result;
        // }
        obj.onload=()=>{
            this.picReduce(obj.result,base64=>{
                this.imgData=base64
            });
        };
    },
    // 圖片壓縮
    picReduce(picObj,callback){
        let img = new Image();
        img.src=picObj;
        img.onload=()=>{
            const w=img.width;
            const h=img.height;
            const scale = w/h;
            const max_w=w>1080?1080:w;
            const max_h=h*max_w/w;
            let canvas=document.createElement("canvas");
            let ctx = canvas.getContext('2d');
            canvas.width=max_w;
            canvas.height=max_h;
            ctx.drawImage(img,0,0,max_w,max_h);
            var base64 = canvas.toDataURL('image/jpeg', 0.7);
            callback(base64)
        }
    },
    handleSubmit(){
      SubmitBaseImg({imgData:this.imgData,imgName:this.imgName}).then(msg=>{
        if(msg.code==200){

        }
      })
    },
  },
  mounted(){},
}

</script>
<style lang='less' scoped>
</style>

2.后台接受base64圖片,通過buffer轉為圖片格式,用stringRandom生成隨機數為圖片名字存儲到服務器

const stringRandom = require('string-random');
var upload_baseImg = async (ctx, next) => {
  let  {imgData,imgName}=ctx.request.body;
  //過濾data:URL
  var base64Data = imgData.replace(/^data:image\/\w+;base64,/, "");
  var dataBuffer = Buffer.from(base64Data, 'base64');
  let name=stringRandom(16, { numbers: true })+'.png';
  console.log('圖',name);
  // let name='圖.png';
  let filePath = path.join(__dirname, '../public/upload/') + `${name}`;
  return new Promise((res,rej)=>{
    fs.writeFile(filePath, dataBuffer, function(err) {
      console.log(111,err);
      if(err){
        res({...errorResObj})
      }else{
        res({
          ...responseObj,
          data:{
            path:`/upload/${name}`,
            name:imgName
          },
        })
      }
    });
  }).then(msg=>{
    ctx.response.body=msg;
  })
  
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM