存储

可恢复上传

了解如何将文件上传至Supabase存储


推荐在以下情况下使用可恢复上传方法:

  • 上传可能超过6MB的大文件
  • 网络稳定性存在顾虑
  • 需要获取上传进度事件

Supabase Storage 实现了 TUS协议 来支持可恢复上传。TUS代表The Upload Server,是一个支持可恢复上传的开放协议。该协议允许在上传中断时从中断处继续上传过程。可以使用 tus-js-client 库或其他支持TUS协议的客户端库(如Uppy)来实现此方法。

以下是使用 tus-js-client 上传文件的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
const tus = require('tus-js-client')const projectId = ''async function uploadFile(bucketName, fileName, file) { const { data: { session } } = await supabase.auth.getSession() return new Promise((resolve, reject) => { var upload = new tus.Upload(file, { endpoint: `https://${projectId}.supabase.co/storage/v1/upload/resumable`, retryDelays: [0, 3000, 5000, 10000, 20000], headers: { authorization: `Bearer ${session.access_token}`, 'x-upsert': 'true', // 可选设置为true以覆盖现有文件 }, uploadDataDuringCreation: true, removeFingerprintOnSuccess: true, // 重要:如果想允许重新上传相同文件 https://github.com/tus/tus-js-client/blob/main/docs/api.md#removefingerprintonsuccess metadata: { bucketName: bucketName, objectName: fileName, contentType: 'image/png', cacheControl: 3600, }, chunkSize: 6 * 1024 * 1024, // 注意:必须设置为6MB(目前),不要修改 onError: function (error) { console.log('上传失败: ' + error) reject(error) }, onProgress: function (bytesUploaded, bytesTotal) { var percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2) console.log(bytesUploaded, bytesTotal, percentage + '%') }, onSuccess: function () { console.log('下载 %s 从 %s', upload.file.name, upload.url) resolve() }, }) // 检查是否有之前的可继续上传 return upload.findPreviousUploads().then(function (previousUploads) { // 找到之前的上传,选择第一个继续 if (previousUploads.length) { upload.resumeFromPreviousUpload(previousUploads[0]) } // 开始上传 upload.start() }) })}

上传URL

使用可恢复上传端点时,存储服务器会为每次上传创建唯一的URL,即使多次上传到相同路径也是如此。所有数据块都将通过PATCH方法上传至该URL。

此唯一上传URL的有效期最长24小时。如果上传未在24小时内完成,URL将过期,您需要重新开始上传。TUS客户端库通常会在前一个URL过期时创建新的URL。

并发控制

当两个或多个客户端上传至同一个上传URL时,仅有一个会成功。其他客户端将收到409 Conflict错误。同一时间只允许1个客户端上传至相同URL,这能防止数据损坏。

当两个或多个客户端使用不同上传URL向相同路径上传文件时,第一个完成上传的客户端会成功,其他客户端将收到409 Conflict错误。

如果设置了x-upsert请求头,则最后一个完成上传的客户端会成功。

Uppy示例

您可以查看使用Uppy的完整示例

Uppy支持多种框架集成:

文件覆盖

当上传文件至已存在路径时,默认行为是返回400 Asset Already Exists错误。如需覆盖特定路径的文件,可将x-upsert请求头设为true

我们建议尽量避免覆盖文件,因为CDN需要一定时间将变更传播至所有边缘节点,这可能导致内容过期。推荐的上传方式是使用新路径,以避免传播延迟和内容过期问题。

了解更多信息,请参阅CDN指南。