使用原生进行文件上传
from的方式
<!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>
enctype=”multipart/form-data” 这个编码方式是啥 为神马要这样呢? 对请求头有何影响
上传成功后的请求头
使用es6的fetchAPI上传图片
<!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>
enctype=”multipart/form-data” 这个编码方式是啥 对请求头有何影响
当使用postman发送上传图片的请求的code
你会发现——WebKitFormBoundary7MA4YWxkTrZu0gW这个动出现三次 这又是啥
先从
Content-Type
enctype=”multipart/form-data”
enctype是编码格式
multipart/form-data 是一种传输文件的格式如下图
boundary=——WebKitFormBoundary7MA4YWxkTrZu0gW

从这个图你就能看出来,最开始是以boundary=——WebKitFormBoundary7MA4YWxkTrZu0gW 开始的,而后面的数据也是
这不就是明显的分割符吗,而boundary的中文意思就是分割符,你再看图片,头部一次尾部一次,剩余的每个数据用这个分分割一次,
而boundary后面的字符知识随机生成出来的分割字符,这种格式很适合传输大数据。
上传的原理
上传不就是将文件读成二进制数据后编码发送给后端吗。说白就是body中的一段数据,其实get请求也能上传文件,实际上数据是发送过去的,只是服务器不认而已
express中实现文文件上传
需要使用的组件:multer
文档:https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
剩余的自己看文档
示例:
const express = require('express');const path = require('path');const multer = require('multer'); // 上传文件的中间件// 路由const router = express.Router();// 默认格式// const upload = multer({// dest: path.resolve(__dirname, '../public/img')// })const storage = multer.diskStorage({// 储存位置destination: function (req, file, cb) {cb(null, path.resolve(__dirname, '../public/img'));},// 文件名 默认是没有后缀名的filename: function (req, file, cb) {const ext = path.extname(file.originalname);const timeStamp = Date.now();const randomStr = Math.random().toString(36).slice(-6);const filename = `${timeStamp}${randomStr}${ext}`;cb(null, filename);},});const upload = multer({storage, // 磁盘存储引擎// 限制数据得大小limits: {fileSize: 1024 * 1024 * 3,},// 那些文件可以上传fileFilter: (req, file, cb) => {cb(null, true);const extname = file.originalname;const whitelist = ['.jpg', '.png', '.gif'];let istrue = false;whitelist.forEach((ele) => {if (extname.includes(ele)) {cb(null, true);istrue = true;} else {cb(null, false);}});if (!istrue) {cb(new Error(`your ext name of ${extname} is not support`));}},});// 单个数据router.post('/', upload.single('img'), (req, res) => {const url = `/upload/${req.file.filename}`;res.send({code: 0,msg: '',data: url,});});module.exports = router;
express.js
const express = require('express');const app = express();app.use('/api/upload', require('./upload'))
