• 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;
      })
      
    }
    
    
  • 相关阅读:
    DataGrid
    取整、取小数点位数
    如何跨浏览器使用连续字符的换行
    如何给 legend 标签设定宽度
    25个简洁优美的网站设计
    重新发现HTML表格
    用户研究角度看设计(2):用户为何视若无睹
    lineheight 属性的继承问题
    jQuery技巧总结
    web2.0网站配色方案
  • 原文地址:https://www.cnblogs.com/miaSlady/p/13218319.html
Copyright © 2020-2023  润新知