具體的屬性能夠查看官方文檔,這裏用到的是:before-upload="beforeAvatarUpload"
這個鉤子函數,看名字就知道這是在圖片上傳前執行的方法,在此能夠進行一些驗證,官方給出了對圖片類型以及大小的驗證,接下來將實現對圖片尺寸的驗證.javascript
<template>
<div class="blog-main-views"> <el-upload class="avatar-uploader" action="https://jsonplaceholder.typicode.com/posts/" :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> </div> </template>
methods: {
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;
}
}
}
複製代碼
這裏咱們把file
參數打印出來看一下html
能夠看到裏面包含了文件名稱,大小,類型,可是沒有圖片的寬高.前端
要實現對圖片寬高的驗證,我這裏是藉助了javascript原生API FileReader
java
先來學習一下這個api
的使用方法,而後再結合elementUI
進行驗證git
FileReader
接口有4個方法,其中3個用來讀取文件,另外一個用來中斷讀取。github
readAsText:該方法有兩個參數,其中第二個參數是文本的編碼方式,默認值爲 UTF-8
。這個方法很是容易理解,將文件以文本方式讀取,讀取的結果便是這個文本文件中的內容。express
readAsBinaryString:該方法將文件讀取爲二進制字符串,一般咱們將它傳送到後端,後端能夠經過這段字符串存儲文件。json
readAsDataURL:這個方法將文件讀取爲一段以data:
開頭的字符串,這段字符串的實質就是 Data URL
,Data URL
是一種將小文件直接嵌入文檔的方案。我這裏就使用這個方法.後端
FileReader
接口包含了一套完整的事件模型,用於捕獲讀取文件時的狀態。api
不管讀取成功或失敗,方法並不會返回讀取結果,這一結果存儲在result
屬性中。
FileReader
接口的使用方式很是簡單,在不考慮瀏覽器兼容的狀況下直接建立實例就能夠了
let reader = new FileReader();
複製代碼
若是考慮瀏覽器,能夠先檢查一下
if(window.FileReader) {
let reader = new FileReader();
}
else {
alert("瀏覽器不支持 換個吧!!");
}
複製代碼
既然是獲取圖片的寬高,那麼我這裏也是藉助了圖片來進行驗證,既然是圖片,咱們就要用到FileReader
接口的readAsDataURL
方法,
beforeAvatarUpload(file) {
let reader = new FileReader();
reader.onload = function () {
let txt = this.result;
let img = document.createElement("img");
img.src = txt;
img.onload = function () {
console.log(img.width);
console.log(img.height);
}
};
reader.readAsDataURL(file);
}
複製代碼
咱們經過readAsDataURL
獲取到的結果,恰好能夠賦給img
標籤做爲src
屬性,而後咱們就能夠經過最簡單的img.width
以及img.height
來獲取寬高了,最後再進行驗證就行了
看一下控制檯打印結果,編碼太長了,主要看一下紅色框裏的部分.看來獲取到寬高是沒問題的了
最後咱們進行驗證,因爲FileReader
接口的onload
方法是異步方法,因此咱們是拿不到img
屬性的,爲此咱們藉助Promise
最後的驗證代碼以下
beforeAvatarUpload(file) {
let _this = this;
return new Promise(resolve => {
let reader = new FileReader()
reader.readAsDataURL(file);
reader.onload = function () {
resolve(this.result)
}
}).then((result) => {
document.querySelector("#img").src = result;
let img = document.querySelector("#img")
img.onload = function () {
console.log(img.width)
console.log(img.height)
const isWidth = img.width < 500
const isHeight = img.height < 500
console.log(isWidth)
console.log(isHeight)
if (!isWidth) {
_this.$message.error('上傳頭像圖片寬度不能超過500!');
}
if (!isHeight) {
_this.$message.error('上傳頭像圖高度不能超過500!');
}
return isWidth && isHeight;
}
})
}
複製代碼
先用一個不符合要求的圖片,
換一個符合要求的圖片
大功告成,這樣就能夠在上傳圖片前進行尺寸驗證啦!
驗證經過之後天然就是要上傳了
目標功能:圖片上傳
操做流程:點擊上傳按鈕->把圖片上傳到服務器->返回圖片URL
<el-upload
class="avatar-uploader"
action="http://81.xx.xx.113:3000/blog/uploadArticleImg"
: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>
複製代碼
action
裏面寫上傳圖片的接口
只有配置了靜態資源文件夾纔可使用URL
的方式訪問圖片,這裏開放靜態資源文件夾必定要在dist
前面,否則的話就會走html
從而訪問不到圖片
//開放靜態資源文件
app.use(express.static(path.join(__dirname, "public")));
// 訪問靜態資源文件 這裏是訪問全部dist目錄下的靜態資源文件
app.use(express.static(path.resolve(__dirname, './dist')));
// 由於是單頁應用 全部請求都走/dist/index.html
app.get('*', function(req, res) {
const html = fs.readFileSync(path.resolve(__dirname, './dist/index.html'), 'utf-8');
res.send(html);
})
複製代碼
服務器端使用的是multer
模塊來處理上傳的圖片,使用post
方式,並添加upload.single('file')
//blog.js
//圖片上傳模塊
const multer = require('multer')
//配置上傳路徑
const upload = multer({ dest: __dirname + '../../public/uploads' })
//upload.single()表示單個文件的上傳
blog.post('/uploadArticleImg', upload.single('file'), require("./blog/uploadArticleImg"));
複製代碼
可是這個multer
模塊處理文件有個坑(更多是我不懂配置),就是它會把上傳的文件名更換成隨機亂碼,而且不會保留後綴,這就致使前端訪問的時候直接下載了這個文件,而不是展現圖片.爲此 ,須要用path
模塊解析原文件後綴名,而後用fs
的方法給文件添加後綴
//uploadArticleImg.js
//引入path模塊
const path = require("path");
//引入fs模塊
const fs = require("fs");
module.exports = async(req, res) => {
//接收文件信息
const file = req.file;
//獲取原文件名的後綴
const suffix = path.parse(req.file.originalname).ext;
//舊的文件名
const oldname = req.file.path;
//新的文件名
const newname = req.file.path + suffix;
//調用fs.renameSync()方法添加後綴
fs.renameSync(oldname, newname);
//獲取圖片的URL
file.url = `http://81.70.96.113:3000/uploads/${file.filename}` + suffix;
//返回文件信息
res.send(file);
}
複製代碼
到這裏就能夠正常上傳圖片,而且返回圖片的URL
偶然間發現新浪雲能夠上傳圖片用,數據量在必定範圍內仍是免費的,減小了本身原本就不富裕的服務器內存壓力.
/* * @Description: 圖片上傳接口 * @Author: hanzhiwei * @Date: 2020-10-07 00:46:47 * @LastEditTime: 2020-10-13 00:42:41 * @FilePath: \blog\serve\route\blog\uploadArticleImg.js */
//引入path模塊
const path = require("path");
//引入fs模塊
const fs = require("fs");
//新浪sdk引用
const sinaCloud = require('scs-sdk');
//配置新浪雲的accessKey和secretKey 我理解的就是帳號密碼
const config = new sinaCloud.Config({
accessKeyId: '2wesaabmtYD4N3SwxkfM',
secretAccessKey: 'e75005531b2e364d72efb8ee729f0825629a158a',
sslEnabled: false
});
//實例化新浪雲儲存
var myBucket = new sinaCloud.S3({ params: { Bucket: 'duwanyu.com' } });
//當前實例生效:
myBucket.config = config;
module.exports = async(req, res) => {
//接收文件信息
const file = req.file;
//獲取原文件名的後綴
const suffix = path.parse(req.file.originalname).ext;
//舊的文件名(模塊生成的亂碼)
const oldname = req.file.path;
//新的文件名
const newname = req.file.path + suffix;
//調用fs.renameSync()方法添加後綴
fs.renameSync(oldname, newname);
//獲取圖片的URL
// file.url = `http://81.70.96.113:3000/uploads/${file.filename}` + suffix;
//原文件名(文件自己名字)
const remoteFilename = req.file.originalname;
//根據新文件名讀取文件
const fileBuffer = fs.readFileSync(newname);
//上傳文件
myBucket.putObject({
ACL: 'public-read', //權限
Bucket: 'duwanyu.com/images', //上傳至duwanyu.com文件夾裏的images文件夾裏
Key: remoteFilename, //上傳到新浪雲的文件名
Body: fileBuffer //文件
}, function(error, response) {
if (error) {
res.json("上傳新浪雲失敗");
} else {
//上傳圖片成功,將圖片地址返回給前端
file.sinaPath = "http://sinacloud.net/duwanyu.com/images/" + remoteFilename;
//獲取圖片的URL
file.url = `http://81.70.96.113:3000/uploads/${file.filename}` + suffix;
//返回文件信息
res.send(file);
}
});
}
複製代碼
大功告成,此時新浪雲就有咱們上傳的圖片啦!
這是我一個開源的收藏網址的項目
項目地址👉👉點擊進入,能夠直接設置爲瀏覽器主頁或者桌面快捷方式進行使用,本人在用,長期維護。
徹底開源,你們能夠隨意研究,二次開發。固然仍是十分歡迎你們點個Star⭐⭐⭐
👉👉源碼連接(gitee) 👉👉源碼連接(github)
🔊項目預覽地址(GitHub Pages):👉👉alanhzw.github.io
🔊項目預覽備用地址(本身的服務器):👉👉warbler.duwanyu.com
🔊源碼地址(gitee):👉👉gitee.com/hzw_0174/wa…
🔊源碼地址(github):👉👉github.com/alanhzw/War…
🔊個人博客:👉👉www.duwanyu.com