WebDAV客户端,用Typescript编写,用于NodeJS和浏览器
https://github.com/kytrun/web...
关于
WebDAV是一种知名的、稳定的、高度灵活的协议,用于通过API与远程文件系统进行交互。由于它是如此广泛,许多文件托管服务,如Box, Nextcloud/ownCloud和Yandex使用它作为其主要接入接口之一。
这个库提供了一个WebDAV客户端接口,使与启用WebDAV的服务的交互变得容易。API返回promises并使用结果进行解析。它解析和准备目录内容请求,以方便使用,并提供获取文件统计数据和配额等内容的方法。
这个库的目的不是遵循RFC或严格遵守标准WebDAV接口,而是提供一个易于使用的客户端API,用于从Node或浏览器使用大多数WebDAV服务。
Node support
此库与NodeJS版本10及以上兼容(为了获得版本6/8的支持,请使用2.. js的版本。对于版本4支持,请使用范围为1.的版本)。版本2。X和1。X不再受支持,因此使用它们的风险由您自己承担。版本3。X已弃用,可能会收到奇数错误修复.
Browser support
WebDAV客户端在浏览器版本3中得到支持。编译设置指定了Internet Explorer 11支持的最低浏览器版本,但是不会定期在该浏览器中进行测试。
尽管您可以选择自己编译这个库的默认入口点(NodeJS),但不建议使用专用的web版本。
您可以通过不同的入口点使用web版本:
import { createClient } from "webdav/web";
浏览器版本使用UMD-style的模块定义,这意味着您可以使用<script>标记在浏览器中加载库。当使用此方法时,库在窗口对象上可用:window. webdav。例如:
const client = window.WebDAV.createClient(/* ... */);
注意:流在浏览器中是不可用的,所以createReadStream和createWriteStream只做保留。调用它们将引发异常。
Types
Typescript类型与这个库一起导出,用于Node构建。所有类型也可以直接从模块导入:
import { AuthType, createClient } from "webdav";
const client = createClient("https://some-server.org", {
authType: AuthType.Digest,
username: "user",
password: "pass"
});
安装
使用npm作为依赖项简单安装:
npm install webdav --save
使用
使用需要通过调用工厂函数createClient创建一个客户端适配器实例:
const { createClient } = require("webdav");
const client = createClient(
"https://webdav.example.com/marie123",
{
username: "marie",
password: "myS3curePa$$w0rd"
}
);
// Get directory contents
const directoryItems = await client.getDirectoryContents("/");
// Outputs a structure like:
// [{
// filename: "/my-file.txt",
// basename: "my-file.txt",
// lastmod: "Mon, 10 Oct 2018 23:24:11 GMT",
// size: 371,
// type: "file"
// }]
Authentication & Connection
WebDAV客户端自动检测在AuthType.None和AuthType.Password之间使用哪种身份验证。如果没有authType提供配置参数。你必须显式指定AuthType.Token 还是 AuthType.Digest
设置authType将在连接时自动管理Authorization标头。
Basic/no authentication
如果服务器不需要身份验证,您可以使用客户端-只需避免在配置中传递任何值给用户名和密码。
要使用基本身份验证,只需在配置中传递用户名和密码。
这个库还允许通过设置相应的属性httpAgent和httpAgent来覆盖内置的HTTP和HTTPS代理。这些应该分别是http.Agent 和 https.Agent 的实例代理。
OAuth tokens
要使用令牌进行身份验证,将令牌数据传递到令牌字段并指定authType:
createClient(
"https://address.com",
{
authType: AuthType.Token,
token: {
access_token: "2YotnFZFEjr1zCsicMWpAA",
token_type: "example",
expires_in: 3600,
refresh_token: "tGzv3JOkF0XG5Qx2TlKWIA",
example_parameter: "example_value"
}
}
);
Digest authentication
如果服务器需要基于摘要的身份验证,您可以通过authType配置参数启用此功能,以及提供用户名和密码:
createClient(
"https://address.com",
{
authType: AuthType.Digest,
username: "someUser",
password: "myS3curePa$$w0rd"
}
);
Client configuration
createClient方法接受一个WebDAV服务URL和一个配置选项参数。
可选配置项如下:
选项 | 默认值 | 描述 |
---|---|---|
authType | null | 要使用的认证类型。如果没有提供,则默认尝试根据是否提供用户名和密码进行检测。 |
headers | {} | 为所有请求提供额外的头信息。这里提供的头被特定于方法的头覆盖,包括Authorization。 |
httpAgent | None | HTTP代理实例。仅支持Node。看到http.Agent。 |
httpsAgent | None | HTTP代理实例。仅支持Node。看到http.Agent。 |
maxBodyLength | None | 允许发送的最大体长(以字节为单位)。 |
maxContentLength | None | 允许接收的最大内容长度,以字节为单位。 |
password | None | 鉴权密码。 |
token | None | 用于身份验证的令牌对象。 |
username | None | 鉴权用户名。 |
withCredentials | None | Axios的凭据包含设置。 |
Client methods
WebDAVClient接口类型包含WebDAV客户端实例的所有方法和签名。
copyFile
将文件从一个位置复制到另一个位置。
await client.copyFile(
"/images/test.jpg",
"/public/img/test.jpg"
);
(filename: string, destination: string, options?: WebDAVMethodOptions) => Promise<void>
KEY | 是否必填 | 描述 |
---|---|---|
filename | Yes | The source filename. |
destination | Yes | The destination filename. |
options | No | Method options. |
createDirectory
创建一个新目录:
await client.createDirectory("/data/system/storage");
(path: string, options?: CreateDirectoryOptions) => Promise<void>
KEY | 是否必填 | 描述 |
---|---|---|
path | Yes | The path to create. |
options | No | Create directory options. |
options.recursive | No | 如果目录不存在,递归地创建目录。 |
Options扩展了方法选项。
递归创建
递归目录创建在请求方面开销很大。进行多个统计请求(现有路径的深度总和+1),以检测路径的哪些部分已经存在,直到找到一个不存在的段—然后只请求创建方法。
例如,递归调用创建路径/a/b/c/d/e,其中/a/b已经存在,将导致3个stat请求(/a, /a/b/ b和/a/b/c)和3个createDirectory请求(/a/b/c, /a/b/c/d和/a/b/c/d/e)。
创建可读流
同步地为远程文件创建可读流。
注意,尽管流立即返回,但文件的连接和获取仍然在后台异步执行。在流开始接收数据之前会有一些延迟。
client
.createReadStream("/video.mp4")
.pipe(fs.createWriteStream("~/video.mp4"));
如果您想只流文件的一部分,你可以在选项参数中指定range。
client
.createReadStream(
"/video.mp4",
{ range: { start: 0, end: 1024 } }
).pipe(fs.createWriteStream("~/video.mp4"));
(filename: string, options?: CreateReadStreamOptions) => Stream.Readable
KEY | 是否必填 | 描述 |
---|---|---|
callback | No | 用请求的响应触发的回调。 |
filename | Yes | The remote file to stream. |
options | No | Read stream options. |
options.range | No | 流范围配置。 |
options.range.start | Yes | Byte-position for the start of the stream. |
options.range.end | No | Byte-position for the end of the stream. |
Options扩展了方法选项。
创建写入流
创建针对远程文件的写流。
注意,尽管流立即返回,但连接和写入远程文件仍然在后台异步执行。在流开始输送数据之前会有一些延迟。
fs
.createReadStream("~/Music/song.mp3")
.pipe(client.createWriteStream("/music/song.mp3"));
(filename: string, options?: CreateWriteStreamOptions, callback?: CreateWriteStreamCallback) => Stream.Writable
KEY | 是否必填 | 描述 |
---|---|---|
filename | Yes | The remote file to stream. |
options | No | Write stream options. |
options.overwrite | No | 如果远程文件已经存在,是否覆盖该文件。默认为true。 |
callback | No | 回调函数,在建立连接并启动流时触发。Callback与请求的响应一起调用。 |
Options扩展了方法选项。
customRequest
可以通过调用customRequest向附加的主机发出自定义请求。自定义请求提供样板身份验证和客户端内部使用的其他请求选项。
const resp: Response = await this.client.customRequest("/alrighty.jpg", {
method: "PROPFIND",
headers: {
Accept: "text/plain",
Depth: "0"
},
responseType: "text"
});
const result: DAVResult = await parseXML(resp.data);
const stat: FileStat = parseStat(result, "/alrighty.jpg", false);
(path: string, requestOptions: RequestOptionsCustom) => Promise<Response>
KEY | 是否必填 | 描述 |
---|---|---|
path | Yes | The path to make a custom request against. |
requestOptions | Yes | 请求选项-所需的参数,如url,方法等-参考RequestOptionsCustom类型定义。 |
request options参数不会扩展方法选项,因为像头这样的东西已经可以指定了。
删除文件
await client.deleteFile("/tmp.dat");`
(filename: string, options?: WebDAVMethodOptions) => Promise<void>
KEY | 是否必填 | 描述 |
---|---|---|
filename | Yes | The file to delete. |
options | No | Method options. |
检查目录或文件是否存在
if (await client.exists("/some/path") === false) {
await client.createDirectory("/some/path");
}
(path: string, options?: WebDAVMethodOptions) => Promise<boolean>
KEY | 是否必填 | 描述 |
---|---|---|
path | Yes | The remote path to check. |
options | No | Method options. |
获取远程目录的内容。返回项目统计数据的数组。
// Get current directory contents:
const contents = await client.getDirectoryContents("/");
// Get all contents:
const contents = await client.getDirectoryContents("/", { deep: true });
Files can be globbed using the glob option (processed using minimatch). When using a glob pattern it is recommended to fetch deep contents:
const images = await client.getDirectoryContents("/", { deep: true, glob: "/**/*.{png,jpg,gif}" });
(path: string, options?: GetDirectoryContentsOptions) => Promise<Array<FileStat> | ResponseDataDetailed<Array<FileStat>>>
KEY | 是否必填 | 描述 |
---|---|---|
path | Yes | The path to fetch the contents of. |
options | No | Configuration options. |
options.deep | No | Fetch deep results (recursive). Defaults to false. |
options.details | No | Fetch detailed results (item stats, headers). Defaults to false. |
options.glob | No | Glob string for matching filenames. Not set by default. |
Options扩展了方法选项。
获取远程文件的内容。默认返回二进制内容(Buffer):
const buff: Buffer = await client.getFileContents("/package.zip");
如果传输的文件比较大,建议使用流。
文本文件也可以获取:
const str: string = await client.getFileContents("/config.json", { format: "text" });
指定maxContentLength选项来改变客户端在请求中可以接收的最大字节数(仅限NodeJS)。
(filename: string, options?: GetFileContentsOptions) => Promise<BufferLike | string | ResponseDataDetailed<BufferLike | string>>
KEY | 是否必填 | 描述 |
---|---|---|
filename | Yes | The file to fetch the contents of. |
options | No | Configuration options. |
options.details No | Fetch detailed results (additional headers). Defaults to false. | |
options.format | No | Whether to fetch binary ("binary") data or textual ("text"). Defaults to "binary". |
Options扩展了方法选项。
你可以使用onDownloadProgress来计算下载的进度:
import { ProgressEvent } from "webdav";
await client.getFileContents("/package.zip", {
onDownloadProgress: (progressEvent: ProgressEvent) => {
// {
// total: 12345600,
// loaded: 54023
// }
}
});
生成一个可以下载文件的公共链接。此方法是同步的。在URL中公开身份验证详细信息。
并非所有服务器都支持此功能。只有基本身份验证和未经身份验证的连接支持此方法。
const downloadLink: string = client.getFileDownloadLink("/image.png");
(filename: string) => string
KEY | 是否必填 | 描述 |
---|---|---|
filename | Yes | The remote file to generate a download link for. |
为文件上传生成URL。此方法是同步的。在URL中公开身份验证详细信息。
const uploadLink: string = client.getFileUploadLink("/image.png");
(filename: string) => string
KEY | 是否必填 | 描述 |
---|---|---|
filename | Yes | The remote file to generate an upload link for. |
获取当前帐户的配额信息:
const quota: DiskQuota = await client.getQuota();
// {
// "used": 1938743,
// "available": "unlimited"
// }
(options?: GetQuotaOptions) => Promise<DiskQuota | null | ResponseDataDetailed<DiskQuota | null>>
KEY | 是否必填 | 描述 |
---|---|---|
options | No | Configuration options. |
options.details | No | Return detailed results (headers etc.). Defaults to false. |
options.path | No | Path used to make the quota request. |
Options扩展了方法选项。
锁定远端资源(使用写锁)。
const lock = await client.lock("/file.doc");
// Later
await client.unlock("/file.doc", lock.token);
(path: string, options?: LockOptions) => Promise<LockResponse>
KEY | 是否必填 | 描述 |
---|---|---|
path | Yes | The path to lock. |
options | No | Configuration options. |
options.timeout | No | WebDAV lock requested timeout. See the WebDAV Timeout header documentation. |
options.refreshToken | No | Previous valid lock token that should be refreshed. |
Options扩展了方法选项。
将文件移动到另一个位置。
await client.moveFile("/file1.png", "/file2.png");
(filename: string, destinationFilename: string, options?: WebDAVMethodOptions) => Promise<void>
KEY | 是否必填 | 描述 |
---|---|---|
filename | Yes | File to move. |
destinationFilename | Yes | Destination filename. |
options | No | Method options. |
向远程文件写入数据。
当文件未被写入时返回false。{override: false}且文件存在),否则为true。
// Write a buffer:
await client.putFileContents("/my/file.jpg", imageBuffer, { overwrite: false });
// Write a text file:
await client.putFileContents("/my/file.txt", str);
指定maxBodyLength选项来改变客户端可以在请求中发送的最大字节数(仅限NodeJS)。当使用{overwrite: false}时,状态为412的响应将被捕获,并且不会抛出错误。
处理上传进度(仅限浏览器):这使用axios onUploadProgress回调函数,它使用本机XMLHttpRequest进度事件。
// Upload a file and log the progress to the console:
await client.putFileContents("/my/file.jpg", imageFile, { onUploadProgress: progress => {
console.log(`Uploaded ${progress.loaded} bytes of ${progress.total}`);
} });
(filename: string, data: string | BufferLike | Stream.Readable, options?: PutFileContentsOptions) => Promise<boolean>
KEY | 是否必填 | 描述 |
---|---|---|
filename | Yes | File to write to. |
data | Yes | The data to write. Can be a string, buffer or a readable stream. |
options | No | Configuration options. |
options.contentLength | No | Data content length override. Either a boolean (true (default) = calculate, false = don't set) or a number indicating the exact byte length of the file. |
options.overwrite | No | Whether or not to override the remote file if it exists. Defaults to true. |
Options扩展了方法选项。
获取一个文件或目录统计对象。返回一个项目统计。
const stat: FileStat = await client.stat("/some/file.tar.gz");
(path: string, options?: StatOptions) => Promise<FileStat | ResponseDataDetailed<FileStat>>
KEY | 是否必填 | 描述 |
---|---|---|
path | Yes | Remote path to stat. |
options | No | Configuration options. |
options.details | No | Return detailed results (headers etc.). Defaults to false. |
Options扩展了方法选项。
使用令牌解锁被锁定的资源。
await client.unlock("/file.doc", lock.token);
(path: string, token:string, options?: WebDAVMethodOptions) => Promise<void>
KEY | 是否必填 | 描述 |
---|---|---|
path | Yes | Remote path to unlock. |
token | Yes | Token string from a previous lock request. |
options | No | Configuration options. |
Options扩展了方法选项。
Custom properties
对于stat这样在底层使用PROPFIND方法的请求,可以为该方法提供自定义请求体,以便服务器可以使用额外/不同的数据进行响应。可以通过在方法选项中设置data属性来重写主体。
Method options
大多数WebDAV方法扩展了WebDAVMethodOptions,允许设置自定义头等内容。
KEY | 是否必填 | 描述 |
---|---|---|
data | No | Optional body/data value to send in the request. This overrides the original body of the request, if applicable. |
headers | No | Optional headers object to apply to the request. These headers override all others, so be careful. |
signal | No | Instance of AbortSignal, for aborting requests. |
常用数据结构
项目统计
项目统计信息是具有描述文件或目录属性的对象。它们类似如下:
{
"filename": "/test",
"basename": "test",
"lastmod": "Tue, 05 Apr 2016 14:39:18 GMT",
"size": 0,
"type": "directory",
"etag": null
}
或者
{
"filename": "/image.jpg",
"basename": "image.jpg",
"lastmod": "Sun, 13 Mar 2016 04:23:32 GMT",
"size": 42497,
"type": "file",
"mime": "image/jpeg",
"etag": "33a728c7f288ede1fecc90ac6a10e062"
}
属性:
Property name | Type | Present | Description |
---|---|---|---|
filename | String | Always | File path of the remote item |
basename | String | Always | Base filename of the remote item, no path |
lastmod | String | Always | Last modification date of the item |
size | Number | Always | File size - 0 for directories |
type | String | Always | Item type - "file" or "directory" |
mime | String | Files only | Mime type - for file items only |
etag | String / null | When supported | ETag of the file |
props | Object | details: true | Props object containing all item properties returned by the server |
详细的回答
返回结果的请求,如getDirectoryContents、getFileContents、getQuota和stat,可以配置为返回更详细的信息,如响应头。将{details: true}传递给它们的options参数以接收如下对象:
KEY | 是否必填 | 描述 |
---|---|---|
data | * | The data returned by the procedure. Will be whatever type is returned by calling without { details: true } |
headers | Object | The response headers. |
status | Number | The numeric status code. |
statusText | String | The status text. |
CORS
CORS是浏览器使用的一种安全强制技术,用于确保在预期上下文之间执行请求。如果目标服务器在从浏览器发出请求时没有返回CORS头,则它可能与这个库冲突。处理这件事是你的责任。
众所周知,ownCloud和Nextcloud服务器默认情况下不会返回友好的CORS头文件,这使得在浏览器上下文中无法使用此库。当然,你可以自己强制添加CORS头文件(Apache或Nginx配置),但这样做的风险自负。
Projects using this WebDAV client
Buttercup Password Manager, Nextcloud Server, Nextcloud Photos, ownCloud SDK, React OxIDE, BackItUp
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。