准备工作
- 一个域名(用来融合CDN加速)
- 七牛云创建一个存储空间
七牛云绑定域名
在注册完七牛云并创建了一个存储空间后,七牛云会给你自动分配一个融合 CDN 测试域名,但是只有30天的有效期。所以要在项目中使用的话需要绑定自己的域名。建议绑定一个二级域名,绑定成功后就可以通过http://xxxx.com/filename来访问到你的资源了。注意绑定的域名要进行CNAME配置,不然是访问不到的。以我的阿里云域名为例:在域名管理新增一条解析规则,选择CHAME类型,主机记录填你的二级域名,记录值填七牛云生成的CNAME值。具体参考
前端代码
前端使用的是mavonEditor自带的上传图片功能和Element-ui的upload组件
- mavonEditor
//省略部分代码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 : ` ,`$vm`为 `this.$refs.md` */ $vm.$img2Url(pos, res.data.img); }) },}复制代码
- element-ui upload组件直接把服务器地址写在action属性里类似于表单的提交方式,组件本身提供了on-success、before-uploda两个钩子函数,分别在成功后和上传前调用,可以把业务代码写在这里面
//省略部分代码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; },}复制代码
服务端代码
服务端代码主要参考,首先需要通过七牛的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服务器就可以了。
原文发布在