目录
安装express和multer
npm i express multer -S
基础使用
前端表单
enctype必须指定multipart/form-data,因为multer只支持这种。
name的值“logo”对应服务器upload.single中的“logo”。
<form action="/postFile" method="post" enctype="multipart/form-data"> <input id="postFile" type="file" name="logo"> <button type="submit">上传</button> </form>
后端服务器文件
- dest对应上传的文件的目录地址。
- upload.single的值“logo”对应前端name中的“logo”。
import express from 'express' import multer from 'multer' const app = express() const upload = multer({ dest: 'uploads/' }) app.post('/postFile', upload.single('logo'), (req, res) => { res.send(req.file) }) app.listen(3000, () => { console.log('服务器开启中') }) --
启动服务。
去页面选择文件上传一张图片,上传成功。
配置上传文件名
我们发现虽然上传了,但是文件不是我们想要的样子,没有后缀,也不知道是我们上传的图片文件。
我们可以对multer进行详细的配置。
- destination配置上传文件的位置
- filename配置文件名,可以利用file上传文件的内容进行配置:
import express from 'express' import multer from 'multer' const app = express() // const upload = multer({ dest: 'uploads/' }) const upload = multer({ storage: multer.diskStorage({ destination: function (req, file, cb) { cb(null, './uploads/') }, filename: function (req, file, cb) { // fieldname是表单的name值,也就是我们设定的“logo”, // originalname是文件上传时的名字,可以根据它获取后缀, // encoding,mimetype 我就不详细介绍了,可以自行输出查看。 const { fieldname, originalname, encoding, mimetype } = file const after = originalname.split('.')[1] ? '.' + originalname.split('.')[1] : '.jpg' cb(null, fieldname + after); } }) }) app.post('/postFile', upload.single('logo'), (req, res) => { res.send(req.file) }) app.listen(3000, () => { console.log('服务器开启中') })
然后我们重启服务器,再上传一次图片,就有了。
使用fetch上传文件
后端问题解决了我们看看前端的问题,表单上传文件不仅拓展差,还会跳转新页面,令人头疼。
我们肯定更希望用js中的fetch手动上传。如果还不会使用fetch可以先移步:fetch异步请求使用详解
我们去掉form表单,自定义一个上传事件。
我的前端页面在8080端口,也做了nginx代理请求到3000端口,你们可以自行修改成自己的请求。
body.append(‘logo’, file)这里的作为key的“logo”代替了原本表单中的name值“logo”的作用。
虽然是post请求,但是不要添加请求头’Content-Type’: ‘multipart/form-data’,上传文件时post已经自动帮你识别了,再加就要报错了。
<body> <input id="postFile" type="file" name="logo"> <button type="button" onclick="upload()">上传</button> </body> <script> const upload = async () => { const body = new FormData() const file = document.getElementById('postFile').files[0] if (file) { body.append('logo', file) const response = await fetch('http://localhost:8080/postFile', { method: 'post', body }) const res = await response.json() console.log(res) } else { alert('请选择文件!') } } </script>
多文件上传
前端表单
- input加上multiple,支持多文件。
- 因为现在是多文件了,就不直接取文件,我们先获取用id获取dom,遍历添加进body,记得“logo”要对应后台“logo”。
<body> <input id="postFile" type="file" name="logo" multiple> <button type="sub" onclick="upload()">上传</button> </body> <script> const upload = async () => { const body = new FormData() const postFile = document.getElementById('postFile') if (postFile.files[0]) { for (const file of postFile.files) { body.append('logo', file) } const response = await fetch('http://localhost:8080/postFile', { method: 'post', body }) const res = await response.json() console.log(res) } else { alert('请选择文件!') } } </script>
后端服务器文件
- upload.single(‘logo’)改成upload.array(‘logo’, 3),后面的数字是限制上传文件数。
- 命名我们就用本来的名字,好区分不同的文件。
import express from 'express' import mysql from 'mysql' import multer from 'multer' const app = express() // const upload = multer({ dest: 'uploads/' }) const upload = multer({ storage: multer.diskStorage({ destination: function (req, file, cb) { cb(null, './uploads/') }, filename: function (req, file, cb) { const { fieldname, originalname, encoding, mimetype } = file // const after = originalname.split('.')[1] ? '.' + originalname.split('.')[1] : '.jpg' cb(null, originalname); } }) }) app.post('/postFile', upload.array('logo', 3), (req, res) => { res.send(req.files) }) app.listen(3000, () => { console.log('服务器开启中') })
大功告成,有帮助的话不妨点个赞吧,如果有什么问题可以评论区提出,会及时更新解决。