七牛云存储
不要着急,最好的总会在最不经意的时候出现。那我们要做的就是:怀揣希望去努力,静待美好的出现。
一、注意点
1、前端调用七牛云接口时,上传的图片类型需为Blob类型
2、图片上传成功后返回一个包含hash和key的对象,key值可以用于获取七牛云中存储的图片地址
3、将图片上传到七牛云后,从七牛云空间中获取图片时可以对图片进行处理(添加图片或文字水印、转码、裁剪、模糊、旋转等操作)
二、完整代码
后端接口Node代码
const http = require('http');
const qiniu = require('qiniu');
const accessKey = ""; // 填写你的七牛云accessKey,登陆七牛云官网右上角头像上点击密钥管理即可获取
const secretKey = ""; // 填写你的七牛云secretKey
const bucket = ""; // 你创建的七牛云存储空间名称,创建流程:对象存储->空间管理->新建空间
http.createServer((req, res, next) => {
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey); // 生成鉴权对象mac
const options = {
scope: bucket
};
const putPolicy = new qiniu.rs.PutPolicy(options);
const uploadToken = putPolicy.uploadToken(mac);
res.writeHead(200, {
'Access-Control-Allow-Origin': '*' // 允许跨域访问
});
res.end(uploadToken);
}).listen(1234, err => { // 监听本地的1234端口号
if (!err) {
console.log('server listen 1234');
} else {
console.log(err);
}
});
前端HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Node+JavaScript实现七牛云存储</title>
<script src="https://unpkg.com/qiniu-js@2.5.5/dist/qiniu.min.js" defer></script>
<style>
.img-box {
width: 200px;
}
.img-box > img {
width: 100%;
}
</style>
</head>
<body>
<form>
<input type="file" name="file" accept="image/*" multiple id="file">
<input type="button" value="提交" id="submit-btn">
</form>
<div class="img-box" id="img-box">
<img src="" id="img">
</div>
<script>
window.addEventListener('DOMContentLoaded', async function() {
const fileInput = document.querySelector('input#file');
const subBtn = document.querySelector('input#submit-btn');
const imgBox = document.querySelector('#img-box');
let token = await getToken();
token = token.value;
subBtn.onclick = async function () {
if (!fileInput.files.length || !token) {
return;
}
let base64 = await fileToBase(fileInput.files[0]);
base64 = base64.value;
const blob = await baseToBlob(base64);
upload(blob.value, fileInput.files[0].name, token);
}
fileInput.onchange = function() { // 将本地选择的图片显示在容器中
if(this.files[0]) {
imgBox.querySelector('#img').setAttribute('src', window.URL.createObjectURL(this.files[0]));
}
};
// 从服务器端获取上传到七牛云空间的Token
function getToken() {
return new Promise((resolve, reject) => {
const ajax = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft YaHei'); // 实例化一个ajax对象
ajax.open('GET', 'http://localhost:1234', true); // 创建Ajax请求
ajax.send(); // 发送Ajax请求
ajax.onreadystatechange = function () {
if (ajax.readyState === 4) {
resolve({ value: ajax.responseText });
}
}
});
}
// 将File类型的文件转换成Base64格式
function fileToBase(file) {
if (file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file); // reader的readAsDataURL方法可以读取本地文件后返回Base64格式
reader.onload = function (res) {
resolve({ value: res.target.result });
}
});
}
}
// 将Base64格式的文件转换成Blob格式
function baseToBlob(base64) {
if (base64.length) {
// Base64格式: data:<mimeType>;base64,<value>
const value = atob(base64.split(';base64,')[1]); // Ascll码转Binary码
const mimeType = base64.split(';base64,')[0].split('data:')[1];
let ia = new Uint8Array(value.length);
for (let i = 0; i < value.length; i++) {
ia[i] = value.charCodeAt(i);
}
return {
value: new Blob([ia], {
type: mimeType
}),
mimeType
}
}
}
// 将Blob格式的图片上传到七牛云存储空间
function upload(blob, name, token) {
if (blob.size) {
// 调用七牛云提供的upload方法建立一次传输连接, 参数(Blob, Key(后期用于从云端取出图片, 不能重复), token, putExtra, config)
const observable = qiniu.upload(blob, `${+new Date()}_${name}`, token);
// 定义图片上传进度对象
const observer = {
// 正在传输时执行
next(res) {
console.log('文件总大小: ', (res.total.size/1024).toFixed(2), 'k; 当前传输进度: ', res.total.percent, '%');
},
// 传输错误时执行
error(res) {
console.log(res);
},
// 传输完成时执行
complete(res) {
console.log('传输完成, key值: ' + res.key);
}
};
// 开始上传图片, 返回一个对象可以用来取消上传
const subscription = observable.subscribe(observer);
// 调用unsubscribe方法可以取消上传
// subscription.unsubscribe();
return subscription;
}
}
});
</script>
</body>
</html>