nodejs 图片上传接口实现

最开始我使用的是阿里云 接口都写好了 结果发现他要收费 后选用七牛云

云存储:阿里云 和 七牛 的比较

阿里云OSS

node OSS参考文档

0.前期准备

建空间
![
获取accessKeyId,accessKeySecret
在这里插入图片描述

1.安装依赖

npm i ali-oss --save
npm i path --save

2.上代码

upload.js

var express = require("express");
const upload_handler = require("../router_handler/uploadHandler");
const multer = require("multer");
var router = express.Router();

 router.post(
   "/upload",
   multer({
     //设置文件存储路径
     dest: "public/image",
   }).array("file", 1),
   upload_handler.upload
 );
module.exports = router;

uploadHandler.js

let OSS = require("ali-oss");
const path = require("path");
const fs = require("fs");
let client = new OSS({
  // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  region: "",
  // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
  accessKeyId: "",
  accessKeySecret: "",
  bucket: "",
  secure: true, //开启https
});
const headers = {
  // 指定该Object被下载时网页的缓存行为。
  // 'Cache-Control': 'no-cache',
  // 指定该Object被下载时的名称。
  // 'Content-Disposition': 'oss_download.txt',
  // 指定该Object被下载时的内容编码格式。
  // 'Content-Encoding': 'UTF-8',
  // 指定过期时间。
  // 'Expires': 'Wed, 08 Jul 2022 16:57:01 GMT',
  // 指定Object的存储类型。
  // 'x-oss-storage-class': 'Standard',
  // 指定Object的访问权限。
  // 'x-oss-object-acl': 'private',
  // 设置Object的标签,可同时设置多个标签。
  // 'x-oss-tagging': 'Tag1=1&Tag2=2',
  // 指定CopyObject操作时是否覆盖同名目标Object。此处设置为true,表示禁止覆盖同名Object。
  // 'x-oss-forbid-overwrite': 'true',
};
upload = (req, res) => {
  // 文件路径
  var filePath = "./" + req.files[0].path; 
  // 文件类型
  var temp = req.files[0].originalname.split("."); 
  var fileType = temp[temp.length - 1]; 
  var lastName = "." + fileType; 
  // 构建图片名
  var fileName = Date.now() + lastName; 
  // 图片重命名
  fs.rename(filePath, "./public/image/" + fileName, async (err) => {
    if (err) {
      return "";
    } else {
      var localFile = "./public/image/" + fileName;
      var key = fileName; 
      try {
        // 填写OSS文件完整路径和本地文件的完整路径。OSS文件完整路径中不能包含Bucket名称。
        // 如果本地文件的完整路径中未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
        const result = await client.put(key, path.normalize(localFile)); 
        // const result = await client.put('exampleobject.txt', path.normalize('D:\\localpath\\examplefile.txt'), { headers });
        fs.unlink(localFile, function () {});
        res.send({
          status: 0,
          message: "上传图片成功!",
          data: result.url,
        });
      } catch (e) {
        console.log(e);
      }
    }
  });
};

3.接口测试

在这里插入图片描述

七牛云对象存储

0.前期准备

建空间
在这里插入图片描述
域名(我暂时用的是测试域名)
在这里插入图片描述

自定义域名设置方法

AccessKey/SecretKey
在这里插入图片描述

1.安装依赖

npm i qiniu

2.上代码

upload.js

const express = require("express");
const router = express.Router();
const multer = require("multer");
const upload_handler = require("../router_handler/uploadHandler");

router.post(
  "/upload",
  multer({
    //设置文件存储路径
    dest: "public/image",
  }).array("file", 1),
  upload_handler.upload
);

module.exports = router;

uploadHandler.js

const fs = require("fs");
const path = require("path");
const formidable = require("formidable");
// 引入七牛模块
var qiniu = require("qiniu");
//要上传的空间名
var bucket = "animal-house-wjy";
var imageUrl = ""; // 域名名称
var accessKey = "";
var secretKey = "";
var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);

var options = {
  scope: bucket,
};
var putPolicy = new qiniu.rs.PutPolicy(options);
var uploadToken = putPolicy.uploadToken(mac);

var config = new qiniu.conf.Config();
config.zone = qiniu.zone.Zone_z2;

exports.upload = (req, res) => {
  // 文件路径
  var filePath = "./" + req.files[0].path;
 // console.log(filePath, "filePath");
  // 文件类型
  var temp = req.files[0].originalname.split(".");
 // console.log(temp, "temp");

  var fileType = temp[temp.length - 1];
 // console.log(fileType, "fileType");

  var lastName = "." + fileType;
 // console.log(lastName, "lastName");

  // 构建图片名
  var fileName = Date.now() + lastName;
 // console.log(fileName, "fileName");

  var formUploader = new qiniu.form_up.FormUploader(config);
  var putExtra = new qiniu.form_up.PutExtra();
 // console.log(uploadToken, "uploadToken");

  // 图片重命名
  fs.rename(filePath, "./public/image/" + fileName, async (err) => {
    if (err) {
      return "";
    } else {
      var localFile = "./public/image/" + fileName;
      var key = fileName;
      console.log(localFile, "localFile");
      console.log(key, "key");
      try {
        // 文件上传 
        formUploader.putFile(
          uploadToken,
          key,
          localFile,
          putExtra,
          function (respErr, respBody, respInfo) {
            if (respErr) {
              return res.cc(respErr);
            }
            if (respInfo.statusCode == 200) {
              var imageSrc = imageUrl + respBody.key;
              res.cc({
                status: 0,
                msg: "上传成功",
                imageUrl: imageSrc,
              });
            } else {
              return res.cc(respBody);
            }

            // 上传之后删除本地文件
            fs.unlinkSync(localFile);
          }
        );
      } catch (e) {
        console.log(e);
      }
    }
  });
};

特别注意:用此方法传入的域名名称要使用http://…… .com/,若直接使用域名…… .com/,传入数据库返回给前端的图片无法显示

3.接口测试

在这里插入图片描述在这里插入图片描述

4.前端代码实现:

<template>
  <div class="all">
 	 <el-upload
          class="avatar-uploader"
          ref="upload"
          action="http://127.0.0.1:8029/upload"
          :show-file-list="false"
          :headers="myHeaders"
          :limit="1"
          :file-list="fileList"
          :before-upload="beforeUpload"
          :on-success="handleSuccess"
          :on-change="handleChange"
        >
          <img
            v-if="userInfo.user_pic"
            :src="userInfo.user_pic"
            class="image"
          />
          <!-- <i v-else class="el-icon-plus avatar-uploader-icon"></i> -->
        </el-upload>
	</div>
</template>
<script>
import axios from "axios";
 data() {
    return { 
      userInfo: {}, 
      // 图片上传headers
      myHeaders: {
        Authorization: window.localStorage.getItem('token')
      },
      fileList: [],
    };
  },
  methods:{
	 // 图片上传处理函数
    handleSuccess(response, file, fileList) {
      console.log(response);
      this.userInfo.user_pic = response.message.imageUrl;
      console.log(this.userInfo.user_pic);
      axios({
        url: "/my/edituserpic",
        method: "post",
        data: qs.stringify({
          user_id: this.userInfo.user_id,
          user_pic: this.userInfo.user_pic,
        }),
      }).then((res) => {
        console.log(res);
        if (res.status !== 200 || res.data.status != 0)
          return this.$message.error("头像修改失败!");
        this.$message.success("头像修改成功!");
        // this.editDialogVisible = false;
        // el-upload 文件上传一次再次上传无反应的解决方法
        this.$refs.upload.clearFiles(); //上传成功之后清除历史记录
        this.getInfo();
      });
    },
    handleChange(file, fileLists) {
      // alert(JSON.stringify(file))
      // this.userInfo.user_pic=fileLists
      // console.log(file);
      // console.log(fileLists);
      // // 本地服务器路径
      // console.log(URL.createObjectURL(file.raw));
      // // 本地电脑路径
      // console.log(document.getElementsByClassName("el-upload__input")[0].value);
    },
    beforeUpload(file) {
      console.log(file);
      const extension =
        file.name.split(".")[1] === "jpg" || "jpeg" || "png" ? true : false;
      const isLt2M = file.size / 1024 / 1024 < 2;
      console.log(file.name.split(".")[1]);
      console.log(extension);
      if (!extension) {
        this.$message.error("上传图片格式为jpg、jpeg或png!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      return isLt2M && extension;
    },
  },
}
</script>
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值