项目
版本

Uppy Tus

@uppy/tus 插件通过封装 tus-js-client 为 Uppy 带来了使用 Tus 的断点续传文件上传功能。

何时应该使用它?

Tus 是基于 HTTP 构建的一种支持断点续传的开放协议。这意味着,即使意外关闭标签页或失去连接,您也可以继续进行,例如,从 10GB 的上传中断处继续,而不是重新开始。

Tus 支持任何语言、任何平台和任何网络。它需要客户端和服务端的集成才能工作。您可以查看客户端和服务端的 实现列表 来找到您首选语言的服务器。您可以在 Tus 服务器本身存储文件,但也可以使用服务集成(如 S3)来外部存储文件。如果您不想托管自己的服务器,请参阅 “是否有托管的 Tus 服务器?” 。

如果您想要可靠且可恢复的上传:使用 @uppy/tus 只需几行代码即可连接到您的 Tus 服务器。

安装

  • npm

    npm install @uppy/tus
    
  • yarn

    yarn add @uppy/tus
    
  • CDN

    <!-- 1. Add CSS to `<head>` -->
    <link href="https://releases.transloadit.com/uppy/v3.27.3/uppy.min.css" rel="stylesheet">
    
    <!-- 2. Initialize -->
    <div id="uppy"></div>
    
    <script type="module">
      import { Uppy, Tus } from "https://releases.transloadit.com/uppy/v3.27.3/uppy.min.mjs"
      new Uppy().use(Tus, { endpoint: 'https://tusd.tusdemo.net/files' })
    </script>
    

使用

快速概览完整的 API。

import Uppy from "@uppy/core";
import Dashboard from "@uppy/dashboard";
import Tus from "@uppy/tus";

import "@uppy/core/dist/style.min.css";
import "@uppy/dashboard/dist/style.min.css";

new Uppy()
  .use(Dashboard, { inline: true, target: "body" })
  .use(Tus, { endpoint: "https://tusd.tusdemo.net/files/" });

API

选项

信息

所有选项都会传递给 tus-js-client,我们在此文档化了那些必需的、添加的或更改的选项。这意味着您也可以传递诸如 onAfterResponse 这样的函数 。

我们建议查看 tus-js-clientAPI 参考 ,以了解支持的内容 。

id

此插件的唯一标识符( string,默认值:'Tus' )。

endpoint

Tus 服务器的 URL( string,默认值:null )。

headers

要随请求一起发送的 HTTP 头部的对象或函数( object | function,默认值:null )。

键是头部名称,值是头部值。

const headers = {
  authorization: `Bearer ${window.getCurrentUserToken()}`,
};

头部值也可以根据文件数据派生,通过提供一个函数。该函数接收一个 Uppy 文件 并必须返回一个对象,其中键是头部名称,值是头部值。

const headers = (file) => {
  return {
    authorization: `Bearer ${window.getCurrentUserToken()}`,
    expires: file.meta.expires,
  };
};

chunkSize

表示 PATCH 请求体最大大小的数字,单位为字节(number,默认值:Infinity)。请注意,此选项仅影响本地浏览器上传。如果需要为远程(Companion)上传设置最大分块大小,您也必须设置 Companion 的 chunkSize 选项。

withCredentials

配置请求以使用 xhr.withCredentials 属性发送 Cookies(boolean,默认值:false)。

远程服务器必须接受 CORS 和凭据。

retryDelays

当上传块失败时,按照定义的毫秒间隔自动重试( Array<number>,默认值:[0, 1000, 3000, 5000] )。

默认情况下,我们首先立即重试;如果失败,则在 1 秒后重试;如果再次失败,则在 3 秒后重试,依此类推。

设置为 null 可以禁用自动重试,如果有任何分块上传失败则立即失败。

onBeforeRequest(req, file)

行为类似于 tus-js-clientonBeforeRequest 函数,但增加了额外的 file 参数。

onShouldRetry: (err, retryAttempt, options, next)

当上传失败时,会调用 onShouldRetry 函数,并传入错误和默认的重试逻辑作为最后一个参数(function)。

默认的重试逻辑采用 指数退避 算法,当服务器(或代理)返回 HTTP 429(请求过多)错误时触发。这意味着如果你的服务器因过载而返回 HTTP 429,@uppy/tus 将会找到理想的平衡点,保持上传而不至于过载。

如果你想扩展此功能,例如在未授权请求上重试(以获取新的认证令牌):

import Uppy from "@uppy/core";
import Tus from "@uppy/tus";
new Uppy().use(Tus, {
  endpoint: "",
  async onBeforeRequest(req) {
    const token = await getAuthToken();
    req.setHeader("Authorization", `Bearer ${token}`);
  },
  onShouldRetry(err, retryAttempt, options, next) {
    if (err?.originalResponse?.getStatus() === 401) {
      return true;
    }
    return next(err);
  },
  async onAfterResponse(req, res) {
    if (res.getStatus() === 401) {
      await refreshAuthToken();
    }
  },
});

allowedMetaFields

传递一个字段名数组来限制将作为 Tus 元数据 添加到上传中的元数据字段( Array,默认:null )。

  • 设置为 ['name'] 仅发送 name 字段。
  • 设置为 null(默认值)发送所有元数据字段。
  • 设置为空数组 [] 不发送任何字段。

limit

限制同时进行的上传数量( number,默认:20 )。

设置为 0 意味着对并发上传没有限制(不推荐)。

常见问题

提示

Tus 网站有详尽的 常见问题解答 ,如果有什么不清楚的,我们也建议在那里查看一下。

文件元数据是如何存储的?

Tus 使用唯一标识符作为文件名以防止命名冲突。为了仍然保留元数据,Tus 还会上传一个额外的 .info 文件,其中包含原始文件名和其他元数据:

{
  "ID": "00007a99d16d4eeb5a3e3c080b6f69da+JHZavdqPSK4VMtarg2yYcNiP8t_kDjN51lBYMJdEyr_wqEotVl8ZBRBSTnWKWenZBwHvbLNz5tQXYp2N7Vdol.04ysQAuw__suTJ4IsCljj0rjyWA6LvV4IwF5P2oom2",
  "Size": 1679852,
  "SizeIsDeferred": false,
  "Offset": 0,
  "MetaData": {
    "filename": "cat.jpg",
    "filetype": "image/jpeg"
  },
  "IsPartial": false,
  "IsFinal": false,
  "PartialUploads": null,
  "Storage": {
    "Bucket": "your-bucket",
    "Key": "some-key",
    "Type": "s3store"
  }
}

如何在发送前更改文件?

如果你想更改文件名,你可以在 onBeforeFileAdded 中进行。

如果你想在请求中发送额外的头部信息,请使用 headersonBeforeRequest

发送后如何更改(或移动)文件?

如果你想保留文件名、提取元数据或移动文件到不同的位置,通常可以使用钩子或事件来实现。这取决于你使用的 Tus 服务器具体是如何操作的。例如,tusd 提供了 钩子 ,而 tus-node-server 则提供了 事件

你推荐使用哪个服务器?

Transloadit 在生产环境中运行了 tusd ,服务于全球数百万次请求。因此我们从实战角度推荐 tusd,但其他公司也通过其他 实现 取得了成功,所以这取决于你的需求 。

是否有托管的 Tus 服务器?

所有 Transloadit 计划 都附带了一个托管的 tusd 服务器。你无需做任何事情即可利用它,使用 @uppy/transloadit 会在幕后自动使用 Tus 。

为什么选择 Tus 而不是直接上传到 AWS S3?

首先:可靠且可恢复的上传。这意味着意外关闭标签页或失去连接后,你可以继续上传,比如 10GB 的文件,而不是重新开始。

Tus 对于大量文件(如 8K)和大文件也非常高效。直接从客户端上传到 AWS S3 也会引入相当多的开销,因为需要更多的请求才能完成流程。

在本文档中