Uppy XHR 上传
@uppy/xhr-upload
插件用于向 HTTP 服务器进行常规上传。
何时使用?
提示
不确定哪个上传器最适合您?阅读 “选择适合您的上传器” 。
当您已有 HTTP 服务器,且不需要 Transloadit 服务或不想运行 tus 服务器时。请注意,即使不运行额外的服务器,通过将 tus 集成到现有服务器中,仍然可以使用 tus. 例如,如果您有一个 Node.js 服务器(或服务器端框架如 Next.js),您可以集成 tus-node-server 。
安装
npm
npm install @uppy/xhr-upload
yarn
yarn add @uppy/xhr-upload
CDN
警告
此捆绑包包含了大部分Uppy插件,因此不建议在生产环境中使用此方法,因为尽管您可能仅仅用到其中一小部分插件,但用户却需要下载全部插件。
然而,这对于加速您的开发环境非常有帮助,所以在起步阶段,请放心使用它来提升开发速度。<!-- 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, XHRUpload } from "https://releases.transloadit.com/uppy/v3.27.3/uppy.min.mjs" new Uppy().use(XHRUpload, { endpoint: 'https://tusd.tusdemo.net/files' }) </script>
使用
API 的快速概览。
import Uppy from "@uppy/core";
import Dashboard from "@uppy/dashboard";
import XHR from "@uppy/xhr-upload";
import "@uppy/core/dist/style.min.css";
import "@uppy/dashboard/dist/style.min.css";
new Uppy()
.use(Dashboard, { inline: true, target: "body" })
.use(XHR, { endpoint: "https://your-domain.com/upload" });
API
选项
id
此插件的唯一标识符( string
,默认:'XHRUpload'
)。
endpoint
HTTP 服务器的 URL( string
,默认:null
)。
method
配置用于上传的 HTTP 方法( string
,默认:'POST'
)。
注意
Uppy 目前未遵循标准,会将方法名称大写。此行为将在未来版本中移除,以使 Uppy 与 Web API 对齐。
formData
配置是否使用 multipart 表单上传,使用 FormData( boolean
,默认:true
)。
这类似于使用包含 <input type="file">
的 <form>
元素进行上传。当设置为 true
时,文件元数据也会作为单独的表单项发送到端点。设为 false
时,则仅发送文件内容。
fieldName
当 formData 设置为 true
时,用作要上传的文件的表单字段名 。
如果 bundle
选项设置为 true
,则默认为 'files[]'
,否则默认为 'file'
。
allowedMetaFields
传递一个字段名称数组来限制将添加到上传中的元数据字段。
- 设置为空数组
[]
表示不发送任何字段。 - 设置为
['name']
表示只发送name
字段。 - 设置为
null
(默认值)表示发送所有元数据字段。
如果 formData 选项设置为 false
,则忽略 metaFields
。
headers
一个对象,包含用于上传请求的 HTTP 头。键是头部名称,值是头部值。
const headers = {
authorization: `Bearer ${window.getCurrentUserToken()}`,
};
头部值也可以从文件数据派生,通过提供一个函数。该函数接收一个 Uppy 文件 ,并必须返回一个对象,其中键是头部名称,值是头部值。
const headers = (file) => {
return {
authorization: `Bearer ${window.getCurrentUserToken()}`,
expires: file.meta.expires,
};
};
注意
当
[bundle](#bundle)
设置为true
时,函数语法不可用。
bundle
将所有文件在一个 multipart 请求中发送( boolean
,默认:false
)。
所有文件将附加到请求中提供的 fieldName
字段中。
警告
当 bundle
设置为 true
时:
要在不同的字段上上传文件,请使用 uppy.setFileState()
来设置文件上的 xhrUpload.fieldName
属性:
uppy.setFileState(fileID, {
xhrUpload: { fieldName: "pic0" },
});
validateStatus
检查响应是否成功( function
,默认:(status, responseText, response) => boolean
)。
- 默认情况下,具有 2xx HTTP 状态码的响应被认为是成功的。
- 当为
true
时,将会调用getResponseData()
并且上传将被标记为成功。 - 当为
false
时,将会调用 两者getResponseData()
和getResponseError()
并且上传将被标记为不成功。
参数
statusCode
是端点返回的数字 HTTP 状态码。responseText
是 XHR 端点响应的字符串形式。response
是 XMLHttpRequest 对象。
注意
此选项仅用于本地上传。来自 Google Drive 或 Instagram 等远程提供商的上传不支持此功能,将始终使用默认值。
getResponseData
从成功的上传中提取响应数据( function
,默认:(responseText, response) => void
)。
responseText
是 XHR 端点响应的字符串形式。response
是 XMLHttpRequest 对象。
JSON 已经自动处理,因此仅在端点以不同格式响应时才应使用此方法。例如,响应 XML 文档的端点:
function getResponseData(responseText, response) {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(responseText, "text/xml");
return {
url: xmlDoc.querySelector("Location").textContent,
};
}
注意
此响应数据将在文件的
.response
属性上可用,并将在 [upload-success
][uppy.upload-success] 事件中发出。
注意 从 Dropbox 或 Instagram 等远程提供商上传文件时,Companion 会将上传响应数据发送到客户端。这也会在
getResponseData()
函数中可用。来自 Companion 的response
对象具有一些以其 XMLHttpRequest 对应项命名的属性 。
getResponseError
从失败的上传中提取错误( function
,默认:(responseText, response) => void
)。
例如,如果端点响应包含一个含 { message }
属性的 JSON 对象,这将向用户显示该消息:
function getResponseError(responseText, response) {
return new Error(JSON.parse(responseText).message);
}
responseUrlFieldName
包含已上传文件位置的字段名( string
,默认:'url'
)。
这是由 getResponseData()
返回的。
timeout: 30 * 1000
如果在这些毫秒内未接收到任何上传进度事件,则中止连接( number
,默认:30_000
)。
请注意,与 XMLHttpRequest.timeout 属性不同,这是一个进度事件之间的计时器:整个上传过程可以比这个值更长。设置为 0
可以禁用此检查。
limit
并行上传的最大文件数量(number
,默认:5
)。
responseType
期望从服务器接收的响应类型,确定如何填充 xhr.response
属性(string
,默认:'text'
)。
可以在自定义的
getResponseData()
回调中访问 xhr.response
属性。此选项设置了 XMLHttpRequest.responseType 属性。只有 ''
、'text'
、'arraybuffer'
、'blob'
和 'document'
被浏览器广泛支持,因此建议使用其中之一。
withCredentials
指示跨站点访问控制请求是否应使用凭据( boolean
,默认:false
)。
`locale:
export default {
strings: {
// 如果上传因长时间暂停而被取消,在 Informer 中显示。
timedOut: "上传暂停了 %{seconds} 秒,正在中止。",
},
};
常见问题解答
如何随上传一起发送元数据?
使用 XHRUpload 时带有 formData: true,文件元数据会随每个上传请求一起发送。您可以使用 uppy.setFileMeta(fileID, data)
,或对所有文件同时使用 uppy.setMeta(data)
来设置文件元数据 。
根据某些文件属性(如大小)设置元数据可能很有用。您可以使用 file-added
事件和 uppy.setFileMeta(fileID, data)
方法来实现这一点:
当文件被添加时,通过监听 file-added
事件,你可以往文件元数据中添加额外信息:
uppy.on('file-added', (file) => {
uppy.setFileMeta(file.id, {
size: file.size,
});
});
现在,一旦上传开始,名为 size
的表单字段将会和文件一起发送到 [上传端点] 。
默认情况下,所有元数据都会被发送,包括 Uppy 的默认 name
和 type
元数据。如果你不希望 name
和 type
这两个元数据属性被发送到你的上传端点,可以使用 metaFields
选项来限制应该发送的字段名。
uppy.use(XHRUpload, {
// 只发送我们自定义的 `size` 元数据字段。
allowedMetaFields: ["size"],
});
如何上传到 PHP 服务器?
XHRUpload 插件的工作方式类似于 <form>
上传。在服务器端,你可以使用 $_FILES
变量来处理上传的文件。参阅 PHP 文档关于 处理文件上传 的部分。
文件上传的默认表单字段是 files[]
,这意味着你需要按照 上传多个文件 中描述的方式来访问 $_FILES
数组:
<?php
// upload.php
$files = $_FILES['files'];
$file_path = $files['tmp_name'][0]; // 文件的临时上传路径
$file_name = $_POST['name']; // 文件的期望名称
move_uploaded_file($file_path, './img/' . basename($file_name)); // 将文件保存在 `img/` 目录下
注意我们使用了 $_POST['name']
而不是 $my_file['name']
。
$my_file['name']
是用户设备上文件的原始名称。而 $_POST['name']
则是上传文件的 name
元数据值,用户可以在 Dashboard 中编辑它。
设置一个自定义的 fieldName
可以让处理 $_FILES
数组变得不那么复杂:
// app.js
uppy.use(XHRUpload, {
endpoint: "/upload.php",
fieldName: "my_file",
});
<?php
// upload.php
$my_file = $_FILES['my_file'];
$file_path = $my_file['tmp_name']; // 文件的临时上传路径
$file_name = $_POST['name']; // 文件的期望名称
move_uploaded_file($file_path, $_SERVER['DOCUMENT_ROOT'] . '/img/' . basename($file_name)); // 将文件保存在服务器根目录下的 `img/` 目录中