- 后端
- 前端
- 云原生
【免费下载链接】hedgedoc
HedgeDoc - Ideas grow better together
HedgeDoc 支持将笔记中的图片上传存储到多种后端(本地文件系统、S3、Azure Blob、imgur、WebDAV),其中 WebDAV 方案允许你复用任意支持 WebDAV 协议的服务器来托管上传文件。本文将基于仓库文档与源码,完整讲解HD_MEDIA_BACKEND_WEBDAV_*三个环境变量的含义与取值规则,并以 Nextcloud 为例给出从创建应用密码到验证上传的完整实操步骤。读完本文,你可以独立为 HedgeDoc 配置一套基于 WebDAV/Nextcloud 的图片存储服务。
一、WebDAV 媒体后端的工作原理
在 HedgeDoc 中,媒体(Media)指与笔记关联的上传内容,目前仅支持图片。所有存储后端都必须实现同一个接口,包含三个方法(见 backend/src/media/media-backend.interface.ts 与设计文档 docs/content/concepts/media.md):
saveFile(uuid, buffer, fileType):保存文件,并返回一段字符串化的元数据供数据库留存,该元数据只在本后端内部使用;deleteFile(uuid, metadata):根据 UUID 与元数据删除远端文件;getFileUrl(uuid, metadata):返回该文件对外可访问的 URL。
对于 WebDAV 后端,HedgeDoc 会在启动时通过PROPFIND请求探测目标目录是否可访问(见 webdav-backend.ts),若请求失败会直接抛错,提示Can't access <url>。因此,配置完成并启动后,WebDAV 服务器必须允许 HedgeDoc 以配置的凭据访问目标目录。
后端的选择在 backend/src/media/media.module.ts 中注册,由 MediaService 依据HD_MEDIA_BACKEND_TYPE的值(filesystem/azure/imgur/s3/webdav)决定实例化哪一个后端。上传时MediaService.saveFile会先对文件做 MIME 类型白名单校验(仅允许 apng、bmp、gif、heif/heic、jpeg、png、svg、tiff、webp,见 media.service.ts),再调用WebdavBackend.saveFile完成写入。
二、核心配置:三个 WebDAV 环境变量
在 HedgeDoc 中,所有配置均通过环境变量(或根目录.env文件)注入。WebDAV 后端只需在配置中加入以下三行(<CONNECTION_STRING>、<UPLOAD_DIR>、<PUBLIC_URL>需替换为实际值):
HD_MEDIA_BACKEND_TYPE="webdav" HD_MEDIA_BACKEND_WEBDAV_CONNECTION_STRING="<CONNECTION_STRING>" HD_MEDIA_BACKEND_WEBDAV_UPLOAD_DIR="<UPLOAD_DIR>" HD_MEDIA_BACKEND_WEBDAV_PUBLIC_URL="<PUBLIC_URL>"对应地,仓库中的配置解析(backend/src/config/media.config.ts)对这三个变量有明确的校验规则,这与使用体验直接相关:
| 环境变量 | 说明 | 校验要求 | 是否必填 |
|---|---|---|---|
HD_MEDIA_BACKEND_TYPE | 媒体后端类型,取webdav时启用本后端 | 必须与五种后端类型之一精确匹配 | 必填 |
HD_MEDIA_BACKEND_WEBDAV_CONNECTION_STRING | WebDAV 服务器的连接地址,含身份信息 | 必须是一个合法的 URL(zod 的z.string().url()) | 必填 |
HD_MEDIA_BACKEND_WEBDAV_UPLOAD_DIR | 上传目标目录;省略则直接上传到 WebDAV 服务器根目录 | 可选字符串,可为空 | 可选 |
HD_MEDIA_BACKEND_WEBDAV_PUBLIC_URL | HedgeDoc 对外访问上传文件的 URL 前缀 | 必须是一个合法的 URL | 必填 |
配置解析使用 zod 校验(同文件中z.discriminatedUnion('type', [...])定义),一旦HD_MEDIA_BACKEND_TYPE之外的关键值非法或缺失,启动时会打印格式化的错误信息并退出,避免带病运行。
2.1 CONNECTION_STRING:连接地址与身份凭据
<CONNECTION_STRING>采用 WebDAV 常见的schema://user:password@url形式,把用户名与密码(如有需要)直接内嵌进 URL,例如:
https://TestUser:passw0rd@cloud.example.com/remote.php/dav/files/TestUser/从源码看,WebdavBackend 会解析该 URL:先以完整连接串为基准,若同时配置了非空的UPLOAD_DIR,则把目录拼接在连接串之后作为最终上传基址;随后用url.username与url.password生成 HTTP Basic Auth 请求头(Basic base64(username:password),见 webdav-backend.ts)。
2.2 UPLOAD_DIR:指定上传目录(可省略)
<UPLOAD_DIR>用于指定上传的目标文件夹,例如HedgeDoc。它不是必填项——如果不设置(即完全不写该变量),HedgeDoc 会把文件直接上传到 WebDAV 服务器的根目录。源码中的对应逻辑是:仅当uploadDir存在且非空字符串时才拼接目录(webdav-backend.ts)。
2.3 PUBLIC_URL:对外访问 URL 前缀
<PUBLIC_URL>指定 HedgeDoc 访问上传文件所用的 URL 前缀。文件名会被直接追加到该前缀之后。例如PUBLIC_URL为https://dav.example.com、文件名为test.png时,访问地址即为https://dav.example.com/test.png。
这与源码行为完全一致:getFileUrl 从数据库元数据中取出文件名,再将其拼接到publicUrl之后返回;MediaService.getFileResponse 对 WebDAV 这类后端返回{ type: 'redirect', url },由媒体重定向控制器(backend/src/media-redirect/media-redirect.controller.ts)将浏览器 302 到该地址。因此PUBLIC_URL必须指向一个能让浏览器直接下载到图片的公开地址。
三、上传与删除的底层行为
理解后端的 HTTP 细节有助于排查故障。WebdavBackend内部使用fetch与 WebDAV 服务器交互:
- 上传(saveFile):以
PUT方法请求baseUrl/<uuid>.<扩展名>,携带Authorization、Content-Type: application/octet-stream与准确的Content-Length,并设置If-None-Match: *头,保证不会覆盖已存在的文件(见 webdav-backend.ts)。上传成功后,后端把{"file":"<uuid>.<ext>"}这样的 JSON 字符串作为 backendData 写入数据库的media_upload表; - 删除(deleteFile):以
DELETE方法请求baseUrl/<文件名>(见 webdav-backend.ts); - 访问(getFileUrl):如上所述,仅拼接
publicUrl与文件名,不发起请求。
需要特别注意的是:CONNECTION_STRING中携带的用户名/密码会出现在配置文件里,因此官方文档建议为上传单独创建一个专用 WebDAV 用户,并尽量使用应用密码(App Password)而不是主密码。
四、Nextcloud 实战配置(完整步骤)
以 Nextcloud 作为 WebDAV 服务器是最常见的用法。以下步骤以 Nextcloud 21(2021 年 4 月撰写指南时的版本)为例,演示用户名为TestUser、生成的应用密码为passw0rd的完整配置链路。由于连接串中包含用户名与密码,强烈建议使用一个专用 Nextcloud 用户来承担上传任务。
- 创建应用密码:登录 Nextcloud 后进入
Settings>Security,由 Nextcloud 生成一个应用密码(本例假设为passw0rd)。 - 创建上传文件夹:在文件(Files)应用中新建一个文件夹用于存放上传内容,例如
HedgeDoc。 - 共享该文件夹:右键/菜单共享刚创建的文件夹。默认配置为
Read Only(只读),本指南按此假设展开;选择Allow upload and editing(允许上传和编辑)同样可行。 - 获取共享链接:创建共享后链接通常已在剪贴板,否则点击
Share link一行末尾的剪贴板图标复制。本例假设共享链接为https://cloud.example.com/s/some-id。 - 拼接下载参数:在该链接末尾追加
/download?path=%2F&files=,得到https://cloud.example.com/s/some-id/download?path=%2F&files=。这正是之后PUBLIC_URL的取值,HedgeDoc 会把文件名追加到其后,使图片通过共享链接的下载端点对外提供。 - 获取 Nextcloud 的 WebDAV 地址:在文件应用的左下角,位于
Settings>WebDAV处。本例假设为https://cloud.example.com/remote.php/dav/files/TestUser/。 - 拼入登录信息:在 URL 协议(通常是
https://)与 URL 其余部分(本例为cloud.example.com/remote.php/dav/files/TestUser/)之间插入username:password@,得到https://TestUser:passw0rd@cloud.example.com/remote.php/dav/files/TestUser/。这就是CONNECTION_STRING。 - 配置 HedgeDoc:
HD_MEDIA_BACKEND_TYPE="webdav" HD_MEDIA_BACKEND_WEBDAV_CONNECTION_STRING="https://TestUser:passw0rd@cloud.example.com/remote.php/dav/files/TestUser/" HD_MEDIA_BACKEND_WEBDAV_UPLOAD_DIR="HedgeDoc" HD_MEDIA_BACKEND_WEBDAV_PUBLIC_URL="https://cloud.example.com/s/some-id/download?path=%2F&files="完成上述配置后重启 HedgeDoc 服务,即可开始使用由 Nextcloud WebDAV 支撑的图片上传:上传时文件以<uuid>.<扩展名>的命名写入TestUser的HedgeDoc目录,笔记中的图片通过共享链接的下载地址对外展示。
五、验证与常见问题
- 启动即验证:
WebdavBackend构造时会对baseUrl发起一次PROPFIND(Depth: 0)请求,非 2xx 响应或网络失败都会导致启动报错Can't access <url>。若服务起不来,优先检查连接串的协议、主机、目录与凭据。 - PUBLIC_URL 必须可公开访问:它仅用于拼 URL,HedgeDoc 自身不代理图片字节流,而是返回 302 重定向。请确认浏览器可以直接访问
PUBLIC_URL + 文件名。 - 文件不会被覆盖:上传请求带
If-None-Match: *,同名文件(UUID 冲突)会失败而不是覆盖,确保历史图片引用不被破坏。 - 目录与凭据的转义:用户名、密码若含
@、:、/等特殊字符,需按 URL 编码规则转义,否则 URL 解析与 Basic Auth 会出错。 - 配置格式要求:
CONNECTION_STRING与PUBLIC_URL必须是合法 URL,UPLOAD_DIR可省略;若省略上传目录,文件将落在 WebDAV 服务器根目录。
六、相关资源
- 官方文档:docs/content/references/config/media/webdav.md(本文的原始依据)
- 配置解析与校验:backend/src/config/media.config.ts
- WebDAV 后端实现:backend/src/media/backends/webdav-backend.ts
- 媒体后端统一接口:backend/src/media/media-backend.interface.ts
- 媒体服务与后端选择逻辑:backend/src/media/media.service.ts
- 后端注册:backend/src/media/media.module.ts
- 媒体设计文档:docs/content/concepts/media.md
- 环境变量总体说明:docs/content/references/config/index.md
- 后端
- 前端
- 云原生
【免费下载链接】hedgedoc
HedgeDoc - Ideas grow better together
相关推荐
使用 S3 兼容对象存储作为 HedgeDoc 图片上传后端:环境变量配置与源码实现全解析
使用 S3 兼容对象存储作为 HedgeDoc 图片上传后端:环境变量配置与源码实现全解析 本文以 HedgeDoc 官方配置文档 docs/content/r
后端前端云原生HedgeDoc 图片上传存储配置指南:使用本地文件系统(Filesystem)作为媒体后端
HedgeDoc 图片上传存储配置指南:使用本地文件系统(Filesystem)作为媒体后端 HedgeDoc 支持将笔记中上传的图片保存到多种存储后端,其中最
后端前端云原生HedgeDoc 使用 Imgur 作为图片上传后端:配置指南与源码原理
HedgeDoc 使用 Imgur 作为图片上传后端:配置指南与源码原理 导读 HedgeDoc 将笔记中上传的图片(Media)统一交由可插拔的存储后端处理,
后端前端云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考