本来是想自己搭建一个图片服务器的,但是七牛云实名认证有免费存储空间的 10G,公司项目也用到。也算给自己增加经验值吧。所以自己用node写了一份。网上也有很多,但参差不齐。关键还是自己多看官方文档吧。
七牛云开发者平台
还有一个坑点 公开 还是 私有,之后会说
如果默认使用免费,存储空间会自动绑定该免费域名(无需CNAME解析),cdn域名管理会多一条记录
如果是添加自定义域名,
比如你域名 abc.com 你可以取 qiniu.adc.com / cdn.adc.com / 等等,之后图片域名路径就是这个了
添加好了要去原来网站做CNAME解析。配置好了如下图,状态成功
常量值最好用个配置文件存储起来,今天这份只是临时做测试用的,编码不规范,见谅
我是让前端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}!`))
自己可以现在网上找在线图片转base64
比如刚刚你域名cdn.abc.com/xxxxxx.png
能正常打开,该功能差不多实现好了
但是如果你这样
别担心,你只是把你存储空间变成私有,公开就行。我怕麻烦,就这样了。文档上有写,可以自己摸索一下。
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
}
});
})
懂我的意思吧
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>