服务器端实现
npm i multer # 解析form-data的数据
依旧是在express生成器生成的目录中进行
先输入命令 npm i multer 目的是为了解析form-data
然后在routes里写接口
然后在app.js中引入 比如 //文件上传
app.use(’/api/v1/f’, require(’./routes/api/common’));
在public中创建一个文件 比如 上传.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>图片上传</title>
</head>
<body>
// 将上传input隐藏,与图片或其他重叠并显示其他,目的是为了美化上传文件的样子
<input type="file" style="display: none;" id="file" />
<img onclick="selFile()" style="cursor: pointer; width: 120px;" src="/images/upload.png" alt="" />
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script>
// 图片上传的时候,服务器端把文件存储在硬盘上,返回一个地址
var imgCtrl = document.getElementById("file");
function selFile() {
imgCtrl.click();
}
imgCtrl.onchange = function (e) {
// console.log(e.target.files);
// FormDate 是原生js里的一个内置对象
const formData = new FormData();
formData.append("avatar", e.target.files[0]);
axios
.post("/api/v1/c/upload_file", formData, {
// 设置请求头 将axios中默认的json格式改为form-data格式
headers: {
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
console.log(res.data);
});
};
</script>
</body>
</html>
然后在routes文件夹中的api文件夹里创建一个名为common.js的文件
const router = require("express").Router();
var multer = require("multer");
//有很多语法用法,是在node_modules中的multer中的README.md查看怎么用找到的
// 1 这样写之后,express生成器生成的目录中的uploads会自动存储上传的文件 但是生成的上传内容没有后缀名
/* const upload = multer({
dest: 'uploads/'
});
router.post('/upload_file', upload.single('avatar'), (req, res) => {
res.json(req.file);
}); */
// 2 在public下手动创建一个名为uploads的文件
var storage = multer.diskStorage({
// 上传目录
destination: function (req, file, cb) {
cb(null, "public/uploads");
},
// 上传之后的文件名,并且带有原始文件的后缀名
filename: function (req, file, cb) {
// 随机名+"-"+时间戳即随机字符串+原始名
cb(null, file.fieldname + "-" + Date.now() + file.originalname);
},
});
var upload = multer({
storage: storage
});
// 在postman中使用接口或者在网页中192.168.17.30:3000//uploads//avatar-1594018067477WIN_20200702_22_39_40_Pro.jpg 均可成功
// avatar参数表示客户端上传时候使用的form表单的name
router.post("/upload_file", upload.single("avatar"), (req, res) => {
// res.json(req.file); 写下面的req.json时就将这个隐藏起来,要不然冲突了
res.json({
code: 1,
info: "/uploads/" + req.file.filename,
});
});
module.exports = router;
1
2
vue-注册demo2
<template>
<div class="reg">
<h1>注册</h1>
<ul>
<li>
<div>
<input type="file" style="display:none" ref="file" @change="fileSelected" />
<img :src="imgUrl" alt @click="changeImg" />
</div>
</li>
<li>
<input type="text" v-model="nickName" placeholder="请输入昵称" />
</li>
<li>
<input type="text" v-model="userName" placeholder="请输入用户名" />
</li>
<li>
<input type="password" v-model="password" placeholder="请输入密码" />
</li>
<li>
<input type="password" v-model="rePassword" placeholder="请再次输入密码" />
</li>
<li>
<button @click="regHandle">注册</button>
</li>
<li>
<router-link :to="{name:'Login'}" class="reg-link">已有帐号,我要登陆</router-link>
</li>
</ul>
</div>
</template>
<script>
// 导出默认的
import request from '../utils/request'
import { serverUrl } from '../utils/config'
import { reg } from '../services/user'
import { setToken } from '../utils/auth'
export default {
data() {
return {
avatar: '',
nickName: '',
userName: '',
password: '',
rePassword: '',
imgUrl: require('../assets/images/up.jpg')
}
},
methods: {
// 文件上传
changeImg() {
this.$refs.file.click()
},
async fileSelected(e) {
console.log(e)
const formData = new FormData()
// 下图有解释
formData.append('file', e.currentTarget.files[0])
const res = await request.post('/api/v1/common/file_upload', formData, {
headers: {
'Coontent-Type': 'multipart/form-data'
}
})
// console.log(res)
this.avatar = res.info
this.imgUrl = serverUrl + res.info
},
// 提交注册
async regHandle() {
if (
this.avatar === '' &&
this.nickName === '' &&
this.userName === '' &&
this.password === ''
) {
alert('请您将信息填写完整')
return
}
if (this.password !== this.rePassword) {
alert('两次输入的密码不一致')
return
}
const res = await reg({
avatar: this.avatar,
nickName: this.nickName,
userName: this.userName,
password: this.password
})
// console.log(res)
if (res.code === 'success') {
alert('恭喜您注册成功')
setToken(res.token)
this.$router.push({ name: 'Login' })
} else {
alert(res.message)
}
}
}
}
</script>