前端文件上传+expressJs后端文件写入
多文件选择
<input type="file" multiple />
下面以单文件为例
方式1:前端FormData + 后端multiparty
前端
//第一种:通过form表单
<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="text" name="filename" />
<input type="submit" value="提交" />
</form>
//第二种:通过FormData
_file是通过<input type='file' />获得的文件
upload_btn_upload.addEventListener('click', function () {
if (!_file) {
console.error('has not select file~~');
return
}
let formData = new FormData()
//前端传入file,filename
formData.append('file', _file)
formData.append('filename', _file.name)
axios.post('/', formData).then(data => {
console.log(data);
}).catch(reson => {
throw reson
})
})
后端
npm i multiparty
/*
multiparty插件的作用
1. 来解析前端传递的FormData格式数据
2. 将解析的文件起一个名字
3. 将文件保存在指定目录
*/
const multiparty = require('multiparty')
const formidable_upload = (req) => {
return new Promise((resolve, reject) => {
//multyparty的配置
const config = {
uploadDir: path.join(__dirname, '../img') //文件写入的目录
}
new multiparty.Form(config).parse(req, (err, fields, files) => {
if (err) {
reject(err)
return
}
resolve({ fields, files })
})
})
}
index.post('/', async (req, res, next) => {
try {
let { fields, files } = await formidable_upload(req)
let file = files.file || {}
res.send({ code: 0, codeText: 'upload_success' })
} catch (err) {
res.send({ code: 1, codeText: err })
}
});
multiparty换名字
new multiparty.Form(config).parse(req, (err, fields, files) => {
fs.rename(files.file[0].path, path.join(__dirname, '../img/newName.jpg'), (err) => {})
})
方法二:base64(只适用于图片)后端spark—md5解码
前端
let upload = document.getElementById('upload2')
, upload_inp = upload.querySelector('.upload_inp')//<input tyype='file' />
let base64 = null
const FileToBase64 = (file) => {
let reader = new FileReader()
return new Promise((resolve) => {
reader.readAsDataURL(file)
reader.onload = function () {
resolve(reader.result)
}
})
}
upload_inp.addEventListener('change', async function () {
let file = this.files[0]
let base64 = FileToBase64(file)
instance.post('/upload_base64', {
//用encodeURIComponent处理一下,防止乱码
file: encodeURIComponent(base64)
, filename: file.name
}, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
})
后端
npm i spark-md5
const writeFile = (res, path, file, filename) => {
return new Promise((resolve, reject) => {
fs.writeFile(path, file, (err) => {
if (err) {
reject(err)
res.send({
code: 1
, codeText: '写入失败'
})
return
}
resolve()
res.send({
code: 0
, codeText: '上传成功'
})
})
index.post('/upload_base64', (req, res, next) => {
let file = req.body.file
, filename = req.body.filename
, spark = new SparkMD5.ArrayBuffer()
, suffix = /\.([0-9a-zA-Z]+)$/.exec(filename)[1] //后缀
, uploadDir = path.join(__dirname, '../img');
//解码
file = decodeURIComponent(file)
//去base64前缀
file = file.replace(/^data:image\/w+;base64,/, '')
//转buffer格式数据
file = Buffer.from(file, 'base64')
//根据file的内容生成唯一的Hash文件名,同一(不同)张图片生成的Hash名一定是一样(不同)的
spark.append(file)
//spark.end()就是spark.append(file)的file生成的hash文件名
let savePath = `${uploadDir}/${spark.end()}.${suffix}`
writeFile(res, savePath, file, filename)
})
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY