前言:本文讲述前后端实现图片上传功能,首先简述JavaScript中的Blob和File对象,并给出base64、blob、url、file四者相互之间的转换,最后给出一个简单的前后端代码demo实例。
一、JavaScript文件相关API
1.1 Blob
Blob(二进制大对象)是一个可以存储大量二进制数据的对象。主要用途包括但不限于存储文件内容、图片、视频等类型的数据。Blob对象可以用来在前端技术中处理文件上传、下载、图像处理等多种场景。
<script>
const data = new Blob([1, 2, 3, 4, 5], { type: 'application/octet-stream' })
console.log('blob data: ', data)
</script>
1.2 File
File是Blob的子类,包含文件更多信息(文件的类型和其他属性等)
File的构造函数接受三个参数
- 一个包含数据的数组,这个数组可以是包含文本、二进制数据或其他 Blob 对象的数组。
- 文件名,用于表示文件的名称,通常包括文件扩展名。
- 可选的文件选项对象,用于指定文件的类型和其他属性
二、base64、blob、url、file相关转换
以下代码实现了base64、blob、url、file四者之间的相互转换。
<img id="test-img">
<script>
// base64
const base64Data = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAIAAACeHvEiAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAEXRFWHRTb2Z0d2FyZQBTbmlwYXN0ZV0Xzt0AAAETSURBVDiN3ZQxqoNAEIbXYKWNAUFLQQuLdN7BSiw8gViIreIVYuUB7G0srT2DvcuCaKUnWBRBfYVgfBpekpcmZKr9Z5jvH5hhiXmewdtxeh/xlRRypxFCfd+v8nK5nE6PnW6UcRxd10UIbcuqqnqe9wKlbVuEkCzLiqIsmTzPsyxjGMayrL8pxHovdV07jmMYhm3bSwZj7Pt+VVXHNoqidF03TXM/yzFomg6CIAzDYRh2paZpkiTRNI1l2TuUaZq28nw+X6/Xo0EURWmadl23yE+6l++j3HZEkiQAAEIYx/HDtqIo1pZfFJ7nBUGAEEIIn/GXJInjuOVNbP86jHFZls8gAACiKNI0fYfy7/ikHX0S5QdklWFq9EOtGAAAAABJRU5ErkJggg==`
// base64 -> blob
const convertBase64UrlToBlob = (urlData) => {
// 去掉url的头,并转换为byte
let bytes = window.atob(urlData.split(',')[1]),
// 处理异常,将ascii码小于0的转换为大于0
ab = new ArrayBuffer(bytes.length),
ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) ia[i] = bytes.charCodeAt(i);
return new Blob([ab], { type: 'image/png' });
}
const blobWithBase64 = convertBase64UrlToBlob(base64Data)
// blob -> url
const urlWithObjectURLBlob = URL.createObjectURL(blobWithBase64);
// blob -> file
const fileWithBlob = new File([blobWithBase64], 'test.png', { type: 'image/png' })
// file -> base64
const reader = new FileReader();
let base64WithFile = '';
reader.readAsDataURL(fileWithBlob)
reader.onload = function () {
base64WithFile = reader.result
console.log({ base64Data, blobWithBase64, fileWithBlob, base64WithFile, urlWithObjectURLBlob })
document.getElementById('test-img').src = urlWithObjectURLBlob
}
// get blob data -> download file
const downloadFile = (url, fileName) => {
var x = new XMLHttpRequest();
x.open("GET", url, true);
x.responseType = 'blob';
x.onload = function (e) {
url = window.URL.createObjectURL(x.response)
var a = document.createElement('a');
a.href = url
a.download = fileName;
a.target = '_blank';
a.click()
}
x.send();
}
</script>
三、前后端实现
3.1 客户端代码
客户端利用表单来进行上传文件,并将文件信息调用接口
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>File Upload</title>
<script>
// 上传本地文件
const uploadFile = () => {
const formData = new FormData();
const file = document.getElementById(‘file’).files[0];
formData.append("file", file);
console.log(‘upload file: ‘, formData, file)
fetch(‘http://localhost:3005/upload', {
method: ‘POST’,
body: formData
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(‘Error:’, error));
}
</script>
</head>
<body>
<form onsubmit="event.preventDefault(); uploadFile();">
<input type="file" id="file" name="file">
<button type="submit">Upload</button>
</form>
</body>
</html>
3.2 服务端代码
利用multer中间件来进行文件相关操作,express搭建一个简单的接口。
Multer是一个Node.js中间件,用于处理multipart/form-data类型的表单数据,它主要用于上传文件。
const express = require('express');
const multer = require('multer');
const cors = require('cors');
const app = express();
app.use(cors());
const port = 3005;
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, ‘uploads/‘)
},
filename: function (req, file, cb) {
cb(null, file.fieldname + ‘-‘ + Date.now() + ‘.’ + file.originalname.split(‘.’).pop())
}
});
const upload = multer({ storage: storage });
app.post(‘/upload’, upload.single(‘file’), (req, res) => {
res.json({ message: ‘File uploaded successfully’, file: req.file.path });
});
app.listen(port, () => {
console.log(Server running at http://localhost:${port}/
);
});
服务端写了一个简单的接口,用来处理前端表单所上传的文件信息,并且将文件保存至指定文件夹
一个比较简单的demo就完成了
评论区