准备工作
- 一个域名(用来融合CDN加速)
- 七牛云创建一个存储空间
七牛云绑定域名
在注册完七牛云并创建了一个存储空间后,七牛云会给你自动分配一个融合 CDN 测试域名,但是只有30天的有效期。所以要在项目中使用的话需要绑定自己的域名。建议绑定一个二级域名,绑定成功后就可以通过http://xxxx.com/filename来访问到你的资源了。注意绑定的域名要进行CNAME配置,不然是访问不到的。以我的阿里云域名为例:在域名管理新增一条解析规则,选择CHAME类型,主机记录填你的二级域名,记录值填七牛云生成的CNAME值。具体参考官方文档
前端代码
前端使用的是mavonEditor自带的上传图片功能和Element-ui的upload组件
- mavonEditor
<template>
<mavon-editor
ref="md"
:toolbars="markdownOption"
v-model="content"
:ishljs='true'
@save="saveBlogging"
@imgAdd="imgAdd"
@imgDel="imgDel"
/>
</template>
//省略部分代码
methods: {
imgAdd(pos, file) {
// 第一步.将图片上传到服务器.
let self = this
let formdata = new FormData();
let $vm = self.$refs.md
formdata.append('file', file)
self.$axios({
url: '/img/uploadImg',
method: 'post',
data: formdata,
headers: {'Content-Type': 'multipart/form-data'},
}).then((res) => {
// 第二步.将返回的url替换到文本原位置![...](0) -> ![...](url)
/**
* $vm 指为mavonEditor实例,可以通过如下两种方式获取
* 1. 通过引入对象获取: `import {mavonEditor} from ...` 等方式引入后,`$vm`为`mavonEditor`
* 2. 通过$refs获取: html声明ref : `<mavon-editor ref=md ></mavon-editor>,`$vm`为 `this.$refs.md`
*/
$vm.$img2Url(pos, res.data.img);
})
},
}
复制代码
- element-ui upload组件直接把服务器地址写在action属性里类似于表单的提交方式,组件本身提供了on-success、before-uploda两个钩子函数,分别在成功后和上传前调用,可以把业务代码写在这里面
<el-upload
class="cover-update"
action="/img/uploadImg"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
//省略部分代码
methods: {
handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw);
},
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传封面图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
},
}
复制代码
服务端代码
服务端代码主要参考七牛官方的SDK,首先需要通过七牛的accessKey和secreKey来获取token。在七牛个人中心的密钥管理可以拿到accesskey和secrekey。然后获取客户端传上来的file后调用七牛的formUploader.putFile()方法就可以上传文件了,成功后默认会返回一个hash和key。
const Router = require('koa-router')
const qiniu = require('qiniu')
const formidable = require('formidable')
let router = new Router({
prefix: '/img'
})
router.post('/uploadImg',async (ctx, next) =>{
try{
let accessKey = '' // 源码删除:七牛云获取 ak,必须配置
let secretKey = '' // 源码删除:七牛云获取 sk, 必须配置
let mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
let options = {
scope: 'octobershen', // 对应七牛云存储空间名称
expires: 7200 //token过期时间
};
let putPolicy = new qiniu.rs.PutPolicy(options);
let uploadToken = putPolicy.uploadToken(mac);
let form = formidable.IncomingForm();
let {respErr, respBody, respInfo, filename} = await new Promise((resolve) => {
form.parse(ctx.req, function (err, fields, file) {
if(file) {
let localFile = file.file.path
let config = new qiniu.conf.Config();
let formUploader = new qiniu.form_up.FormUploader(config);
let putExtra = new qiniu.form_up.PutExtra();
let key= file.file.name;
formUploader.putFile(uploadToken, key, localFile, putExtra, function(respErr, respBody, respInfo) {
resolve({
respErr,
respBody,
respInfo,
filename: key
})
})
}
})
})
ctx.body = {
respErr,
img: `http://image.shenchangbin.top/${respBody.key}`,//在七牛云上配置域名
hash: respBody.hash,
status: respInfo.statusCode,
filename: respBody.key
}
}catch(error) {
ctx.body = {
code: -1,
error: error
}
}
})
复制代码
踩坑
测试时发现有些图片可以上传有些图片上传报403的错误,这个是由于Nginx对上传的文件大小做了默认1M的限制,于是修改Nginx的配置文件,在nginx.conf中加入client_max_body_size 10m #大小按自己的需求然后重启Nginx服务器就可以了。
原文发布在个人博客