具体的属性能够查看官方文档,这里用到的是: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