node篇 七牛云图片上传与删除

本来是想自己搭建一个图片服务器的,但是七牛云实名认证有免费存储空间的 10G,公司项目也用到。也算给自己增加经验值吧。所以自己用node写了一份。网上也有很多,但参差不齐。关键还是自己多看官方文档吧。

七牛云开发者平台

项目准备

  • 注册一个七牛云账号
  • 创建存储空间
    node篇 七牛云图片上传与删除_第1张图片
    创建的时候会提示两个选项绑定自定义域名和免费的一个月试用。

还有一个坑点 公开 还是 私有,之后会说

如果默认使用免费,存储空间会自动绑定该免费域名(无需CNAME解析),cdn域名管理会多一条记录

如果是添加自定义域名,
node篇 七牛云图片上传与删除_第2张图片
比如你域名 abc.com 你可以取 qiniu.adc.com / cdn.adc.com / 等等,之后图片域名路径就是这个了

添加好了要去原来网站做CNAME解析。配置好了如下图,状态成功

一个免费,一个自定义
node篇 七牛云图片上传与删除_第3张图片

创建好了,还要知道AK值和SK值才能编程。
node篇 七牛云图片上传与删除_第4张图片

文件上传

常量值最好用个配置文件存储起来,今天这份只是临时做测试用的,编码不规范,见谅

我是让前端base64转码,post请求,body中 imgData参数接收

const express = require('express')
const uploadrouter = express.Router()
const path = require('path')
const fs = require('fs')
const app = express()
const qiniu = require('qiniu')
const bodyParser = require("body-parser");

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());



const port = 3000

app.use(express.static(path.join(__dirname, 'public')));

app.use('/qiniu',uploadrouter)

uploadrouter.post('/upload', (req, res) => {
  let accessKey = 'ak'
  let secretKey = 'sk'
  let bucket = '存储空间名'

  var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);

  //要上传的空间
  var options = {
    scope: bucket,
    returnBody: '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}'
  };

  // 构建上传凭证
  var putPolicy = new qiniu.rs.PutPolicy(options);
  var uploadToken = putPolicy.uploadToken(mac);

  var config = new qiniu.conf.Config();
  config.zone = qiniu.zone.Zone_z2; // 华南区 写你自己的



  var imgData = req.body.imgData;
  // 构建图片名
  var fileName = Date.now() + '.png';
  // 构建图片路径
  var filePath = './public/tmp/' + fileName;
  //过滤data:URL
  var base64Data = imgData.replace(/^data:image\/\w+;base64,/, "");
  var dataBuffer = Buffer.from(base64Data, 'base64');
  fs.writeFile(filePath, dataBuffer, function(err) {
      if(err){
        res.end(JSON.stringify({status:'102',msg:'文件写入失败'})); 
      }else{

          var localFile = filePath;
          var formUploader = new qiniu.form_up.FormUploader(config);
          var putExtra = new qiniu.form_up.PutExtra();
          var key = fileName;

          // 文件上传
          formUploader.putFile(uploadToken, key, localFile, putExtra, function(respErr,
            respBody, respInfo) {
            if (respErr) {
              res.end(JSON.stringify({status:'-1',msg:'上传失败',error:respErr}));   
            }
            if (respInfo.statusCode == 200) {
              var imageSrc = respBody.key; // 这里可以拼接你访问的域名
              res.end(JSON.stringify({status:'200',msg:'上传成功',imageUrl:imageSrc}));   
            } else {
              res.end(JSON.stringify({status:'-1',msg:'上传失败',error:JSON.stringify(respBody)}));  
            }
            // 上传之后删除本地文件
            fs.unlinkSync(filePath);
          });
      }
  });

})

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

postman测试

自己可以现在网上找在线图片转base64
node篇 七牛云图片上传与删除_第5张图片
node篇 七牛云图片上传与删除_第6张图片
比如刚刚你域名cdn.abc.com/xxxxxx.png

能正常打开,该功能差不多实现好了

但是如果你这样node篇 七牛云图片上传与删除_第7张图片
别担心,你只是把你存储空间变成私有,公开就行。我怕麻烦,就这样了。文档上有写,可以自己摸索一下。

文件删除

uploadrouter.post('/delete',(req,res)=>{

  let accessKey = 'ak'
  let secretKey = 'sk'

  var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
  var config = new qiniu.conf.Config();
  //config.useHttpsDomain = true;
  config.zone = qiniu.zone.Zone_z2; // 华南
  var bucketManager = new qiniu.rs.BucketManager(mac, config);

  var bucket = "xxx";
  var key = req.body.fileName; // 传递文件名

  bucketManager.delete(bucket, key, function(err, respBody, respInfo) {
    if (err) {
      console.log(err);
      //throw err;
    } else {
       console.log(respBody,respInfo) // 最后还是res.end
    } 
  });
})

node篇 七牛云图片上传与删除_第8张图片
到时你去自己存储空间里看看行不行

懂我的意思吧

app.all('*', function (req, res, next) {
  // 设置请求头为允许跨域
  res.header('Access-Control-Allow-Origin', '*');
  // 设置服务器支持的所有头信息字段
  res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild, sessionToken');
  // 设置服务器支持的所有跨域请求的方法
  res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  if (req.method.toLowerCase() == 'options') {
      res.send(200);  // 让options尝试请求快速结束
  } else {
      next();
  }
});

vue elementUI 以上传为例

<template>
  <div class="hello">
    <h1>{{ msg }}h1>
    <el-upload
      ref="uploadForm"
      action="no"
      :on-change="handleChange"
      :http-request="submit"
      list-type="picture-card"
      multiple
      :limit="6"
      :on-remove="removeHandler"
      :auto-upload="false"
    >
      <i class="el-icon-plus">i>
      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件div>
    el-upload>

    <el-button type="primary" @click="submitUpload">手动上传el-button>
  div>
template>

<script>
import axios from "axios";
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  data() {
    return {
      fileList: [],
      imgBase64Array: [],
    };
  },
  methods: {
    handleChange(file) {
      this.fileList.push(file);
    },
    submitUpload() {
        this.$refs.uploadForm.submit();
    },

    removeHandler(file) {
      let index = this.fileList.indexOf(file.uid);
      this.fileList.splice(index, 1);
    },

    getBase64(file) {
      //把图片转成base64编码
      return new Promise((resolve, reject) => {
        let reader = new FileReader();
        reader.readAsDataURL(file.raw);
        reader.onload = function() {
          resolve(this.result);
        };
        reader.onerror = function(error) {
          reject(error);
        };
      });
    },
    async getList() {
      var arr = [];
      const result = this.fileList;
      for (let i = 0; i < result.length; i++) {
        await this.getBase64(result[i]).then((res) => {
          arr.push(res);
        });
      }
      this.imgBase64Array = arr;
    },
    upload(imgData) {
      return new Promise((resolve, reject) => {
        axios({
            method: 'post',
            url: "http://XXXXXXXXXX/qiniu/upload",
            data: {
              imgData: imgData,
            },
          })
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
    },
    async submit() {
      await this.getList();
      const result = this.imgBase64Array;
      var arr = [];
      for (let i = 0; i < result.length; i++) {
        await this.upload(result[i]).then((res) => {
          arr.push(res);
        });
      }
      console.log(arr,222222222);
    },
  },
};
script>


<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
style>

你可能感兴趣的:(Node.js)