有关分片上传的总结
最新做了分片上传的需求,林林总总出现了很多问题,特此记录总结。
1. 跨域问题
跨域是在开发过程中始终难受又不得不解决问题。
最开始的跨域是跨域名和跨端口,使用 axios 的 withCredentials 配置依然不能正常访问。因此使用了 Chrome 的非安全模式进行开发,等正式接口上线后再进行联调。
chrome
开启非安全模式方式:
- 完全退出 chrome
- 命令行运行:
sudo open -a Google\ Chrome --args --disable-web-security --user-data-dir=xxxxx/xxxxxx/xxxx
(xxxxx/xxxxxx/xxxx
为本地准备存放 chrome 路径)。
第二处跨域出现在正式接口上线后的联调过程中,在上传过程中创建会话(session)以及查询上传情况的接口都可正常访问,偏偏上传文件的动作被 chrome 摁了下来。经过反复排查发现,上传文件的接口未正确处理 options 信息,亦无正确配置请求头,因此依然跨域。
配置 options (需要后端配合):
- post 请求如果 content-type 为 application/json 就不再是简单请求,必须使用处理复杂请求的方式。
- 后端需响应 options 请求并返回 HttpStatus.OK(通常值是 200)。
- 后端 response 的 header 配置 accept 不能为 *,必须是具体的请求头。
第三处跨域出现在上线后,线上为 https 而开发使用的 http。两则虽然域名相同但是协议不同,依然违反了同源政策。处理方式为等待后端上线 https 接口,别无他法。
总结:前端开发中因为跨域安全问题,所耗费的精力往往超过了需求本身。
2.JavaScript 伪多线程的问题
JavaScript 使用的是多进程单线程,使用 setTimeout 等异步代码实际上是需要等待主线程执行完毕后才进行异步执行。因此一旦主线程阻塞,异步线程无论如何也不会执行。
setTimeout( () => console.log('2'), 0)
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
console.log('1')
// 执行结果是 111111111 2
开发中遇到的问题是切片时同时起 10 个接口请求阻塞主线程,即便是起 setTimeout 发送心跳包依然无济于事。最后使用异步线程启动链接,并且间隔(5秒)启动下一个,大大缓解卡顿情况。
3.upload 改造问题
切片上传使用 element 的 upload 上传组件,但是经过了一定改造。但是目前使用的是包装模式在 upload 上包了一层、而且代码和 vue 页面放在一起,仍有优化空间。未来的目标是把上传模块整合进 upload,成为一个新组件。