
七牛云存儲
不要著急,最好的總會在最不經(jīng)意的時候出現(xiàn)。那我們要做的就是:懷揣希望去努力,靜待美好的出現(xiàn)。
一、注意點
1、前端調(diào)用七牛云接口時,上傳的圖片類型需為Blob類型
2、圖片上傳成功后返回一個包含hash和key的對象,key值可以用于獲取七牛云中存儲的圖片地址
3、將圖片上傳到七牛云后,從七牛云空間中獲取圖片時可以對圖片進行處理(添加圖片或文字水印、轉(zhuǎn)碼、裁剪、模糊、旋轉(zhuǎn)等操作)
二、完整代碼
后端接口Node代碼
const http = require('http');
const qiniu = require('qiniu');
const accessKey = ""; // 填寫你的七牛云accessKey,登陸七牛云官網(wǎng)右上角頭像上點擊密鑰管理即可獲取
const secretKey = ""; // 填寫你的七牛云secretKey
const bucket = ""; // 你創(chuàng)建的七牛云存儲空間名稱,創(chuàng)建流程:對象存儲->空間管理->新建空間
http.createServer((req, res, next) => {
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey); // 生成鑒權(quán)對象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 => { // 監(jiān)聽本地的1234端口號
if (!err) {
console.log('server listen 1234');
} else {
console.log(err);
}
});
前端HTML代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Node+JavaScript實現(xiàn)七牛云存儲</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]));
}
};
// 從服務(wù)器端獲取上傳到七牛云空間的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); // 創(chuàng)建Ajax請求
ajax.send(); // 發(fā)送Ajax請求
ajax.onreadystatechange = function () {
if (ajax.readyState === 4) {
resolve({ value: ajax.responseText });
}
}
});
}
// 將File類型的文件轉(zhuǎn)換成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格式的文件轉(zhuǎn)換成Blob格式
function baseToBlob(base64) {
if (base64.length) {
// Base64格式: data:<mimeType>;base64,<value>
const value = atob(base64.split(';base64,')[1]); // Ascll碼轉(zhuǎn)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) {
// 調(diào)用七牛云提供的upload方法建立一次傳輸連接, 參數(shù)(Blob, Key(后期用于從云端取出圖片, 不能重復(fù)), token, putExtra, config)
const observable = qiniu.upload(blob, `${+new Date()}_${name}`, token);
// 定義圖片上傳進度對象
const observer = {
// 正在傳輸時執(zhí)行
next(res) {
console.log('文件總大小: ', (res.total.size/1024).toFixed(2), 'k; 當前傳輸進度: ', res.total.percent, '%');
},
// 傳輸錯誤時執(zhí)行
error(res) {
console.log(res);
},
// 傳輸完成時執(zhí)行
complete(res) {
console.log('傳輸完成, key值: ' + res.key);
}
};
// 開始上傳圖片, 返回一個對象可以用來取消上傳
const subscription = observable.subscribe(observer);
// 調(diào)用unsubscribe方法可以取消上傳
// subscription.unsubscribe();
return subscription;
}
}
});
</script>
</body>
</html>