演示
技术栈
- 前端:Vue
- 后端:nodejs、express、multer
本地端口
- 前端:8080
- nodejs:3000
- nginx:3001
前端部分
<script>
import axios from "@/axios";
export default {
data() {
return {
imgs: [] //已上传图片列表
};
},
methods: {
fileChange(e) {
// 获取file文件
const file = e.target.files[0];
if (file.size / 1024 / 1024 > 5) {
alert("图片大于5M上传失败");
return;
}
// 通过FormData进行接口传输
const formData = new FormData();
formData.append("imgFile", file);
// 接口上传
axios.uploadImg(formData).then(response => {
if (response.code == 200) {
// 1、通过base64 预览
// let reader = new FileReader();
// reader.readAsDataURL(file);
// reader.onload = e => {
// this.imgs.push(e.target.result);
// };
// 2、这里通过接口返回图片地址预览
this.imgs.push("//localhost:3001" + response.data);
}
});
}
}
};
</script>
<template>
<div>
<div class="photo">
<div v-for="(img,index) in imgs" :key="index">
<img class="upload-img" :src="img" alt />
</div>
<div class="default">
<img src="@/assets/img/img_photo.png" alt />
<input type="file" name="file" accept="image/*" @change="fileChange($event)" />
</div>
</div>
</div>
</template>
axios.js
import axios from "axios";
const instance = axios.create();
axios.defaults.withCredentials = true;
//请求拦截器
instance.interceptors.request.use(
config => {
return config;
},
error => {
return Promise.reject(error);
}
);
//响应拦截器
instance.interceptors.response.use(
response => {
return Promise.resolve(response.data);
},
error => {
return Promise.reject(error);
}
);
export default {
//上传图片
uploadImg: data => {
return instance.post("//localhost:3000/upload", data);
}
};
流程:
- 通过input的onchange事件获取到本地图片文件。
- 调用接口传输FormData格式的图片文件。
- 拿到接口返回的服务器图片地址进行预览。
后端部分
const express = require('express')
const upload = require("../lib/upload");
const app = express();
// .single(fieldname)
// 接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.file。
app.post('/upload', upload.single("imgFile"), function (req, res, next) {
res.json({
code: 200,
data: "/" + req.file.filename,
msg: "success"
});
})
/lib/upload.js
const multer = require("multer");
const upload = multer({
storage: multer.diskStorage({
destination: "/uploads", //本地保存的目录(E:\uploads)
filename: function(req, file, cb) {
//保存的文件名
cb(null, file.fieldname + "-" + Date.now() + "-" + file.originalname);
}
}),
//限制上传大小5M和同时上传的数量
limits: {
fileSize: 1024 * 1024 * 5,
files: 5
},
//依据mime文件类型过滤
fileFilter: function(req, file, cb) {
const allowArr = ["image/jpeg", "image/gif", "image/png"];
if (allowArr.indexOf(file.mimetype) > -1) {
cb(null, true);
} else {
cb(new Error("文件类型不正确"));
}
}
});
module.exports = upload;
当前端调用"/upload",在multer中间件,我们自定义了保存的目录、文件名,同时限制了大小、数量和文件类型。
最后返回给前端的数据data中,是一个自定义后的文件名。
为了让前端访问到保存后的文件,使用了nginx做代理。
Nginx代理
nginx.conf
server {
listen 3001;
server_name localhost;
location / {
root E:\uploads;
}
}
代理的端口是3001,目录是我们自定义的保存目录"E:\uploads"。
这样前端<img>标签的src设置为"localhost:3001+图片名",就可以显示图片了。