一、文件上传
相关对象
files:通过 input 标签读取的文件对象
blob:不可变的二进制内容,
formData:用于和后端传输的对象
fileReader:把文件读取为某种形式
- input 标签,type=file,选中文件后通过 e.target.files[0] 获取上传的文件 fileObj
- 读取文件,根据文件内容,借助第三方插件生成 md5(秒传、断点续传需要此步骤)
- 请求 文件检查接口,传入md5和文件名,检查服务端是否存在即将上传的文件(服务端比较 md5 有三种情况:1 存在 md5 且已经上传完成,服务端就自己复制一份,并返回成功标识,前端不需要再请求文件上传接口,实现文件秒传;2 如果存在 md5 ,但是文件还没有上传完成,就会返回文件上传成功的部分的位置给前端(断点续传);3 如果不存在 md5 标识没有上传过,服务端没有该文件,返回标识,前端从头开始上传
- 如果是 3 中的情况 2,前端拿到返回的文件上传成功部分的位置,从该位置开始切片进行上传
- 如果是 3 中的情况 3,前端就从文件开始的位置进行切片上传
切片上传:
6. files 对象和 blob 对象都可以通过文件的 fileObj.slice(start, end) 方法进行切片
7. 对文件内容根据文件size和切片的size,通过 slice 进行切片
8. 循环调用上传文件的接口,接口如参数就是 md5 值、fileName、file(切片内容)、offset(切片位置),每次循环完成以后,需要对切片位置进行计算
二、websocket
if(window.webSocket == undefined || window.webSocket == null) {
// socket 地址
var url = 'ws://' + websocketUrl + account;
// 实例化 WebSocket 对象
window.webSocket = new WebSocket(url);
// 建立 WebSocket 连接
window.webSocket.onopen = () => {
_that.longstart(); // 成功建立连接后,创建心跳检测
};
// 前端获取到后端通过 onmessage 返回到数据
window.webSocket.onmessage = (evt) => {
_that.longstart(); //心跳重置
}
// 监听连接失败
window.webSocket.onerror = () => {
this.websocketonerror("webSocket.onerror")
};
// 监听连接关闭
window.webSocket.onclose = () => {
this.websocketonerror("webSocket.onclose")
}
} else {
this.retryNum ++;
window.webSocket = null
this.websocketonerror() //连接失败时,进行重连
}
websocketonerror() {
this.retryNum <= 6 && this.connectWebSocket(); //失败、关闭重连
},
// 心跳检测
longstart() {
//1、通过关闭定时器和倒计时进行重置心跳
this.retryNum = 0;
clearInterval(this.timeoutObj)
clearTimeout(this.serverTimeoutObj);
// 2、每隔10s向后端发送一条商议好的数据
this.timeoutObj = setInterval(()=>{
if(this.retryNum <= 6) { //只允许重试6
// console.log('监测心跳')
let data='{"body": "pong","direct":"request"}'
window.webSocket && window.webSocket.send(data);
// 3、发送数据 5s后没有接收到返回的数据进行关闭websocket重连
this.serverTimeoutObj = setTimeout(()=>{
this.lockReconnect = true;
this.retryNum ++;
// console.log("后台挂掉,没有心跳了....,重试了"+this.retryNum+"次");
if(window.webSocket) {
window.webSocket.close();
}
}, 5000);
} else {
clearInterval(this.timeoutObj)
clearTimeout(this.serverTimeoutObj);
}
},10000)
},
destroySocket() {
if (window.webSocket) {
window.webSocket.close(); // 离开路由之后断开websocket连接
}
clearInterval(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
}
beforeDestroy() {
this.lockReconnect = false;
this.destroySocket();
},
三、如何做技术选型
- 满足项目需求
- 可控性,如果这个技术出现了 bug 是否有人可以解决
- 成熟稳定(社区否活跃、配套插件是否完善、官方文档是否齐全、更新迭代以后功能是否可以兼容)
- 易用性,学习成本
四、前端鉴权
权限管理分类:
1,菜单权限控制(页面级):接口返回菜单权限组成的数组,前端将异步路由进行匹配,再通过 addRouter 添加到路由中
2,按钮权限控制(按钮级):接口返回按钮权限组成的数组,增加指令,指令的 mounted 中,根据安全权限数组进行匹配,匹配成功,插入按钮,否则不插入
3,接口权限控制(url级别):接口中使用 token