multer
官网:https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
由于单独封装上传文件的功能,需要做的事情比较繁琐这里直接使用multer库来操作
服务器
安装multer
npm i multer@1.4.2
创建路由器
由于图片作为静态资源(除非你想保存base64图片到数据库),所以不需要service层,只需要定义一个路由层就可以
const express = require('express');const router = express.Router();const multer = require('multer');const path = require('path');const storage = multer.diskStorage({destination: function (req, file, cb) {cb(null, path.resolve(__dirname, '../../public/upload'))},filename: function (req, file, cb) {// 时间戳 - 6位随机字符.文件后缀const timeStamp = Date.now();const ramdomStr = Math.random().toString(36).slice(-6);const ext = path.extname(file.originalname);const filename = `${timeStamp}-${ramdomStr}${ext}`;cb(null, filename);}})const upload = multer({storage,limits: {fileSize: 1024 * 2014 * 10},fileFilter(req, file, cb) {// 文件名const extname = path.extname(file.originalname);const whiteList = ['.jpg', '.gif', '.png', '.jpeg'];if (whiteList.includes(extname)) {cb(null, true);} else {cb(new Error(`you ext name of ${extname} is not support`));}}});router.post('/', upload.single('avatar'), function (req, res, next) {const url = `http://localhost:12306/upload/${req.file.filename}`;res.send({success: true,uid: "0",name: "IMG.png",state: "done",url: url,downloadURL: url,imgURL: url,size: 2000})})module.exports = router;
storage,用来定义图片上传以后保存图片位置和文件名字的信息const storage = multer.diskStorage({destination: function (req, file, cb) {cb(null, path.resolve(__dirname, '../../public/upload'))},filename: function (req, file, cb) {// 时间戳 - 6位随机字符.文件后缀const timeStamp = Date.now();const ramdomStr = Math.random().toString(36).slice(-6);const ext = path.extname(file.originalname);const filename = `${timeStamp}-${ramdomStr}${ext}`;cb(null, filename);}})
destination,定义上传图片的存放的位置- req: 请求头部的相关信息
- file: 上传的文件的相关信息
- cb: 回调函数,第一个参数表示没有错误产生,否则会直接报错,第二个参数存放文件的文件夹路径
filename: 自定义存放文件的文件的名字- cb: 回调函数,第一个参数表示没有错误产生,否则会直接报错,第二个参数表示格式化后的文件名
upload:对象const upload = multer({storage,limits: {fileSize: 1024 * 2014 * 10},fileFilter(req, file, cb) {// 文件名const extname = path.extname(file.originalname);const whiteList = ['.jpg', '.gif', '.png', '.jpeg'];if (whiteList.includes(extname)) {cb(null, true);} else {cb(new Error(`you ext name of ${extname} is not support`));}}});
- multer返回一个对象,
- storage: 定义文件存放的路径和文件名
- limits: 文件大小,字节为单位
- fileFilter:过滤上传文件
- 参数: req,请求头,file,文件相关的信息,cb回调函数
- whiteList: 定义允许上传的文件类型
- 如果允许就直接回调会true
cb(null,true) - 如果不允许,直接抛出错误给客户端
cb(new Error(you ext name of ${extname} is not support));第一个参数有值,会作为错误处理
创建路由
``json router.post('/', upload.single('avatar'), function (req, res, next) { const url =http://localhost:12306/upload/${req.file.filename}`; res.send({success: true,uid: "0",name: "IMG.png",state: "done",url: url,downloadURL: url,imgURL: url,size: 2000
}) })
- 返回的数据格式可以自定义<a name="W3BL7"></a>## 引用上传路由```jsonapp.use('/api/upload', require('./api/upload'))
客户端
原生表单
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><form action="/api/upload" method="POST" enctype="multipart/form-data"><p><input type="text" name="a" /></p><p><input type="file" name="img" /></p><p><button>提交</button></p></form></body></html>
- entype :一定是要写成
multipart/form-data,否则会有问题 - method: post
- 会直接把文件作为文件对象上传
ajax
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><p><input type="text" name="a" /></p><p><input type="file" name="img" accept="image/*" multiple /></p><p><button>提交</button></p><img src="" alt="" /><script>function upload() {const inpA = document.querySelector("[name=a]");const inpFile = document.querySelector("[name=img]");const img = document.querySelector("img");const formData = new FormData(); //帮助你构建form-data格式的消息体formData.append("a", inpA.value);for (const file of inpFile.files) {formData.append("img", file, file.name);}fetch("/api/upload", {body: formData,method: "POST",}).then((resp) => resp.json()).then((resp) => {console.log(resp);if (resp.code) {//有错误alert(resp.msg);} else {img.src = resp.data;}});}document.querySelector("button").onclick = upload;</script></body></html>
- 需要借助
new FileReader()来创建文件封装数据格式,否则数据发送到服务器会有问题
