likes
comments
collection
share

Node+Vue实现图片上传七牛云

作者站长头像
站长
· 阅读数 18

前言

在项目开发中,我们经常会遇到图片上传的情况,比如说头像上传,某些表单或者文章需要插入图片上传。在本文中,主要记录一下Node服务端+Vue前端实现图片上传的两种情况。

获取七牛云的token

不管是在md中插入图片的上传形式还是使用el-upload的头像上传七牛云,都需要获取七牛云的token,在本文中我们获取token主要使用node实现。

首先我们在node项目中,可以在config文件夹下新建一个七牛云的配置文件,主要用于保存七牛云的accessKey,secretKey和options

    // 七牛云上传文件的配置 accessKey和secretKey在密钥管理中获取,scope为你要上传的七牛云空间名称
    // returnBody为返回的格式,可以根据自身需要进行设置
    accessKey: "",
    secretKey: "",
    options: {
        scope: "",
        returnBody: `{"key":"$(key)",
        "bucket":"$(bucket)",
        "name":"$(fname)"}`
    },

更详细的信息可以访问七牛云的官方SDK文档

然后可以新建一个上传文件的路由,用于书写获取token的接口

var express = require('express');
var router = express.Router();

let opt = require('../config/qiniu.js');
let qiniu = require('qiniu');

// 鉴权
let mac = new qiniu.auth.digest.Mac(opt.accessKey, opt.secretKey);

// 上传凭证
let putPolicy = new qiniu.rs.PutPolicy(opt.options);
// 设置token有效时间
const tokenExpireTime = 86400;
qiniu.conf.ACCESS_TOKEN_EXPIRE_TIME = tokenExpireTime;
let uploadToken = putPolicy.uploadToken(mac);

router.get('/upload', async (req, res, next) => {
    res.header("Cache-Control", "max-age=0, private, must-revalidate");
    res.header("Pragma", "no-cache");
    res.header("Expires", "0");
    if (uploadToken) {
        res.json({
            code: 200,
            token: uploadToken
        })
    }
})

前端访问该接口即可获得上传的token

通过el-upload上传图片

首先我们需要在template中使用el-upload标签

<el-upload class="avatar-uploader" :action="uploadUrl" :data="qiniuToken" :before-upload="beforeUpload" :on-success="handleAvatarSuccess" :show-file-list="false">
 <img v-if="imgUrl" :src="imgUrl" class="avatar">
 <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>

这里我们需要注意几个参数,分别是uploadUrl,qiniuToken,beforeUpload,handleAvatarSuccess

uploadUrl是上传的地址,可以在七牛云的官方文档中查到,本文使用华南地区的地址,为uploadUrl: 'upload-z2.qiniup.com'。

qiniuToken是我们访问后端接口得到的token,以及key值(key值为上传图片的图片名,为了区分不同,一般我们需要对图片名进行重命名,格式为:用户名+当前时间戳+整数随机数),qiniuToken:{token: '', key: ''}。

beforeUpload是上传前的回调函数,可以在这个获取到token以及重命名key。

handleAvatarSuccess是上传成功的回调函数,可以接受一个res参数,得到上传成功之后返回的数据,具体返回的数据格式在node的七牛云配置文件的returnBody中设置。

通过md编辑器上传图片

这里我们使用的md编辑器是mavonEditor

在template中使用mavonEditor标签

<mavonEditor v-model="content" ref="md" @change="change" @imgAdd="imgAdd" @imgDel="imgDel" style="min-height: 800px; width: 95%;" />

这里我们需要注意imgAdd和imgDel两个方法

imgAdd方法用于添加,关于前端直接上传图片,我们可以参考七牛云官方文档的 JavaScript SDK

this.token我们需要使用前面那个接口进行获取。

        imgAdd(pos, file) {
            // console.log(this.userInfo);
            let fileName = `${this.userInfo.username}_${Date.now()}_${Math.round(Math.random() * 100)}`
            // console.log(fileName);
            // console.log(fileName,pos, file);
            if (this.token) {
                this.pos = pos
                let observable = qiniu.upload(
                    file,
                    fileName,
                    this.token,
                    { fname: fileName, params: {}, mimeType: null },
                    { useCdnDomain: true }
                );
                observable.subscribe(
                    this.next,
                    this.error,
                    this.complete
                )
            }
        },

注意点: observable.subscribe的参数顺序不能出错,next,error,complete方法可以自行定义,三个方法都可以接收一个res参数,获取最终结果,complete方法是成功上传之后的回调函数。

补充说明

根据key获取七牛云的图片链接

router.get('/getImgUrl', async (req, res, next) => {
    let key = req.query.key;
    var config = new qiniu.conf.Config();
    var bucketManager = new qiniu.rs.BucketManager(mac, config);
    var privateBucketDomain = '你的外链域名';
    var deadline = parseInt(Date.now() / 1000) + 3600; // 1小时过期
    var privateDownloadUrl = bucketManager.privateDownloadUrl(privateBucketDomain, key, deadline);
    res.json({
        code: 200,
        msg: '获取成功',
        data: privateDownloadUrl
    })
})

获取md图片语法中的url方法

str为md语法的字符串

// 切割md格式的字符串获取图片的url
export const getStrUrl = (str) => {
    let url = str.match(/!\[(image.png)\]\((.*?)\)/g);
    if(url == null) return [];
    let reg = /\((.+?)\)/gi;

    let res = url.map(item => {
        return item.match(reg)[0].replace(/\(|\)/g, "");
    })
    return res;
}

获取七牛云图片地址中的key值

传入的参数为url数组

// 切割七牛云图片的url,获取其中的key值
export const getUrlKey = (urlList) => {
    if(urlList.length === 0) return [];
    return urlList.map(item => {
        let match = item.match(/.com\/([^?]+)/);
        return match ? match[1] : null;
    })
}
转载自:https://juejin.cn/post/7296753988817092643
评论
请登录