TUS断点上传
使用tus将文件上传到minio中,并结合后端接口做token校验
使用Docker构建
Dockerfile
version: '3.3'
services:
tus-server:
image: tusio/tusd
container_name: tus-server
ports:
- 1080:1080
privileged: true
environment:
AWS_ACCESS_KEY_ID: minioadmin
AWS_SECRET_ACCESS_KEY: minioadmin
AWS_REGION: us-east-1
command:
["--s3-bucket","bucketName","--s3-endpoint","http://192.168.10.39:9000","--base-path","/files/","--hooks-http-forward-headers","Authorization","--hooks-http","http://192.168.10.35:80/oss/tus-hooks","--hooks-enabled-events","pre-create,post-receive,pre-finish,post-finish"]
networks:
default:
driver: bridge
参数说明
--s3-bucket
对应的是bucket名称--s3-endpoint
对应minIO的地址--base-path
tus的上传地址--hooks-http-forward-headers
钩子回调时,需要转发的请求头,这边需要把业务方带的Authorization请求头转发给后端,用于鉴权--hooks-http
钩子回调的后端地址,用于做一些中间操作,比如鉴权等--hooks-enabled-events
哪些事件需要做回调,基本上是文件上传的一个生命周期内的回调事件。比如上传前,上传完成前,上传完成后等
启动服务
docker-compose up -d
定义后端钩子接口
伪代码逻辑
@PostMapping("/oss/tus-hooks")
public Result verify(HttpServletRequest request, @RequestBody Map<String, Object> map) {
ossService.verify(request, map);
return this.success();
}
public void verify(HttpServletRequest request, Map<String, Object> map) {
String token = request.getHeader("Authorization");
//校验token是否合法,伪代码,根据业务自定义
Assert.isTrue(checkToken(token), "无权操作")
String hookName = request.getHeader("hook-name");
if ("post-finish".equals(hookName)) {
//上传完成,得到文件信息,并存储到数据库中或者返回
TusDTO tusDto = JSONUtil.toBean(JSONUtil.toJsonStr(map), TusDTO.class);
save(tusDto);
}
}
TusDTO的json格式
{
"upload": {
"id": "",
"size": 0,
"metaData": {
"filename": "",
"filetype": "",
"name": "",
"relativePath": "",
"type": ""
},
"storage": {
"bucket": "",
"key": "",
"type": ""
}
},
"httpRequest": {
"method": "",
"uri": "",
"remoteAddress": ""
}
}
前端
使用Uppy.js断点上传
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Uppy</title>
<link href="https://releases.transloadit.com/uppy/v2.3.2/uppy.min.css" rel="stylesheet">
</head>
<body>
<div id="drag-drop-area"></div>
<script src="https://releases.transloadit.com/uppy/v2.3.2/uppy.min.js"></script>
<script>
var uppy = new Uppy.Core()
.use(Uppy.Dashboard, {
inline: true,
target: '#drag-drop-area'
})
// endpoint为tusdocker启动的接口地址 ,header中带上token
.use(Uppy.Tus, {endpoint: 'http://10.66.38.175:1080/files/',headers:{
"Authorization": "Bearer 1aed50be-d6a8-4b72-9ae9-3cba0e83cc0d"
}})
uppy.on('complete', (result) => {
console.log('Upload complete! We’ve uploaded these files:', result.successful)
})
</script>
</body>
</html>