# 简易项目
cnpm init egg --type=simple
npx create-nuxt-app front
# 项目规范
commitlint,eslint,prettier,
husky 验证
git flow actions 验证
# 登录权限
图片验证码 svg-captcha
密码加密 md5
session 模式 后端 setCookie 前端无需操作鉴权, redis 存储 取值
jwt 模式 前端登录后 后端将登录信息和过期时间加密成一个 token,前端存入 localstorage 并在 axios 为每个请求携带上 jsonwebtoken
middleware 验证头部 header.authorization 的 token
邮箱验证 nodemailer
# 文件上传
浏览器选择文件 => 上传到服务器 => 返回上传进度 => 保存到服务器
# 为什么要用 multipart/form-data
因为application/x-www-form-urlencoded
不适合用于传输大型二进制数据或者包含非 ASCII 字符的数据。平常我们使用这个类型都是把表单数据使用 url 编码后传送给后端,二进制文件无法一起编码进去。
而使用application/json
,后端需要对文本进行特殊的解析,效率较低
# 多种格式上传
# FormData
const file = document.getElementById('file').files[0];
var form = new FormData();
form.append('file', file);
# Blob
const json = { hello: "world" };
const blob = new Blob([JSON.stringify(json, null, 2)], { type: 'application/json' });
const form = new FormData();
form.append('file', blob, '1.json');
axios.post('http://localhost:7787/files', form);
# ArrayBuffer
const bufferArrary = [137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,1,0,0,0,1,1,3,0,0,0,37,219,86,202,0,0,0,6,80,76,84,69,0,0,255,128,128,128,76,108,191,213,0,0,0,9,112,72,89,115,0,0,14,196,0,0,14,196,1,149,43,14,27,0,0,0,10,73,68,65,84,8,153,99,96,0,0,0,2,0,1,244,113,100,166,0,0,0,0,73,69,78,68,174,66,96,130];
const array = Uint8Array.from(bufferArrary);
const blob = new Blob([array], {type: 'image/png'});
const form = new FormData();
form.append('file', blob, '1.png');
axios.post('http://localhost:7787/files', form)
# Base64
const base64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABlBMVEUAAP+AgIBMbL/VAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAACklEQVQImWNgAAAAAgAB9HFkpgAAAABJRU5ErkJggg==';
const byteCharacters = atob(base64);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const array = Uint8Array.from(byteNumbers);
const blob = new Blob([array], {type: 'image/png'});
const form = new FormData();
form.append('file', blob, '1.png');
axios.post('http://localhost:7787/files', form);
base64 编解码
//解码
var decodedData = window.atob(encodedData);
//编码
var encodedData = window.btoa(stringToEncode);
# FileReader
**FileReader**
对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File
(opens new window) 或 Blob
(opens new window) 对象指定要读取的文件或数据。
# 如何做出亮点
- 上传文件格式验证
- 验证后缀,但是无法防范恶意改名文件
- 二进制流验证 (hexdunm) 一个可靠的文件校验
- 断点续传
- 对文件进行切片,计算 md5 然后按数组上传
- 秒传,计算 Md5 然后进行比较
- 大文件 使用 webwork 计算
- fiber 架构,利用空闲时间计算
- 对文件进行抽样数据再计算 md5
- 并发数控制+错误重试
- 并发 + tcp 冷启动
- 思考
- 碎片清理
- 文件碎片存储在多个机器上
- 文件碎片备份
- 兼容性更好的 requestidleCallback
- 抽样 hash + 全量 hash 双重判断
- websocket 推送
- cdn
- ...
# 不同事件上传 + 进度条
拖拽上传
drag.addEventListener("dragover", () => {});
drag.addEventListener("dragleave", () => {});
drag.addEventListener("drop", () => {});