1. 图片上传的原理
图片上传其实就是利用html控件,将图片的二进制信息通过ajax请求发送到后台之后,后台程序拿到图片的信息并存储到服务器的一个文件夹中,这就完成了文件的上传 。
2.使用FormData对象构造表单键值对
let formData = new FormData();
formData.append("uploadFile", file.files[0]);
这样子就可以将文件对象封装起来方便发送。
3.使用FileReader进行图片预览
function previewImage(e) {
var reader = new FileReader();
// 文件读取完毕后会加载这个函数
reader.onload = function (e) {
// reader里面会有一个result将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的
内容
image.src = e.target.result;
};
// 将内容读取为base64的URL字符串
reader.readAsDataURL(e.target.files[0]);
}
4.使用ajax发送上传请求
xhr.open("post", "http://localhost:8080/upload", true);
// 将文件封装到formdata中后 发送到后端
xhr.send(formData);
5.后端使用Multer插件处理文件
// 当前端发送upload的post请求时匹配到这个接口
// upload.single("") 意思是接受键名为uploadFile的file
app.post("/upload", upload.single("uploadFile"), (req, res) => {
// 如果没有文件
if (!req.file) {
res.json({ ok: false });
return;
}
// 重命名文件 并移动文件到public目录下
let oldPath = path.join(__dirname, req.file.path);
let newPath = path.join(__dirname, "public/uploads/" + req.file.originalname);
fs.rename(oldPath, newPath, (err) => {
if (err) {
res.json({ ok: false });
console.log(err);
} else {
res.json("ok");
}
});
});
6.全部代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>文件上传</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<input type="file" name="file" id="file" enctype="multipart/form-data"/>
<button id="upload" type="button">上传</button>
<span id="progress">0</span>
<img id="image" src="" width="200" />
</body>
<script>
(function () {
let file = document.querySelector("#file");
let upload = document.querySelector("#upload");
let progress = document.querySelector("#progress");
let image = document.querySelector("#image");
let xhr = new XMLHttpRequest();
//upload.addEventListener("click", uploadFile);
upload.onclick = uploadFile;
file.addEventListener("change", previewImage);
//点击上传
function uploadFile(e) {
let formData = new FormData();
formData.append("uploadFile", file.files[0]);
xhr.onload = uploadSuccess;
xhr.upload.onprogress = setProgress;
xhr.open("post", "http://localhost:8080/upload", true);
xhr.send(formData);
}
// 成功上传
function uploadSuccess(event) {
if (xhr.readyState === 4) {
console.log(xhr.responseText);
}
}
// 进度条
function setProgress(e) {
if (e.lengthComputable) {
let complete = Number.parseInt((e.loaded / e.total) * 100);
progress.innerHTML = complete + "%";
}
}
// 图片预览
function previewImage(e) {
var reader = new FileReader();
reader.onload = function (e) {
image.src = e.target.result;
};
reader.readAsDataURL(e.target.files[0]);
}
})();
</script>
</html>
const express = require("express");
const path = require("path");
const upload = require("multer")({
dest: "uploads/",
});
const fs = require("fs");
const port = 8080;
const app = express();
app.use(express.static(path.join(__dirname, "public")));
//设置跨域访问
app.all("*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", " 3.2.1");
res.header("Content-Type", "application/json;charset=utf-8");
// 访问权交给下一个中间件
next();
});
app.post("/upload", upload.single("uploadFile"), (req, res) => {
// 如果没有文件
if (!req.file) {
res.json({ ok: false });
return;
}
// 重命名文件
let oldPath = path.join(__dirname, req.file.path);
let newPath = path.join(__dirname, "public/uploads/" + req.file.originalname);
fs.rename(oldPath, newPath, (err) => {
if (err) {
res.json({ ok: false });
console.log(err);
} else {
res.json("ok");
}
});
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});