文件上传
使用的是 express 搭建的 nodejs 服务器
form 表单
注意设置 enctype: multipart/form-data 属性,否则服务器将无法正确解析表单数据
<form action="/api/upload" method="POST" enctype="multipart/form-data">
<p>
<input type="file" name="img123" accept="image/*">
</p>
<p>
<input type="text" name="text">
</p>
<p>
<button type="submit">提交</button>
</p>
</form>
formData
客户端
-
创建 formData 对象,
new FormData
-
添加选择的文件
-
发送 fetch 请求 注意: fetch Api 的服务器响应必须是 json 格式,其他格式会出错!
-
把上传后的图片地址赋值给 img 的 src
<p>
<input type="file" name="img" accept="image/*">
</p>
<p>
<input type="text" name="img">
</p>
<p>
<button type="submit">提交</button>
</p>
<img src="" alt="" id="resp">
function upload() {
const formData = new FormData()
const inpImg = document.querySelector('input[name=img]')
const inpText = document.querySelector('input[name=text]')
const img = document.getElementById('img')
formData.append('text', inpText.value)
for (const file of inpImg.files) {
formData.append('img', file, file.name) // 键 数据 文件名
}
fetch('/api/upload', {
body: formData,
method: 'POST'
})
.then(resp => resp.json()) // 返回值必须是json格式
.then(res => {
img.src = res.data
})
}
const btn = document.getElementsByTagName('button')[0]
btn.onclick = upload
服务端
使用 multer
中间件
-
配置文件上传处理
- 设置 storage 磁盘存储引擎: 存储文件路径 文件名
- 设置 limits 文件存储大小
- 设置过滤文件 fileFilter
-
最好不要把 multer 设置为全局中间件,只在文件上传的 api 中配置
-
返回客户端存储后的文件路径,返回 json 格式是最好的
const multer = require('multer')
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.resolve(__dirname, '../public', 'uploads'))
},
filename: function (req, file, cb) {
const ext = path.extname(file.originalname)
const profix = Math.random().toString(36).slice(-6)
const middle = new Date().toLocaleDateString()
const filename = profix + middle + ext
cb(null, file.fieldname + '-' + filename)
}
})
function fileFilter(req,file,cb){
const ext = path.extname(file.originalname)
const whiteList = ['.jpg','.png']
if(whiteList.includes(ext)){
cb(null,true)
}else{
cb(new Error(`your ext ${ext} is not be supported`))
}
}
var upload = multer({
storage,
limits: {
fileSize: 500 * 1024
},
fileFilter,
})
router.post('/', upload.single('img'), (req, res) => {
const url = `uploads/${req.file.filename}`
res.send({
code: 0,
msg: '',
data: url
})
})