DSH 学习资料站 · FTP 自动上传方案

DSH 资料站 FTP 自动上传方案

把 one 学习资料站每次更新后的 index.html 和新页面,自动上传到 FTP 网站空间的完整方案: 架构流程、涉及文件、凭据安全、配置项、实测结果与边界说明。

01需求与目标

  • 核心目标:每次 index.html 被更新、或新增了 .html 页面后,自动同步到网站空间。
  • 目标站点:一个 FTP 网站空间(服务器地址保存在 dsh 凭据文件中,不对外公开)。
  • 安全要求:凭据受保护——不写入脚本、不写入系统注册表、不随站点上传。
  • 易用要求:日常只需双击一个入口,其余自动化完成。

02整体方案与流程

在原有"问答 → 生成网页 → 刷新入口"的基础上,追加一步自动上传:

双击入口更新入口.bat
重建入口页update-index.ps1
读取凭据~/.dsh/.credentials.yaml
上传所有 HTMLupload-ftp.ps1
网站空间ftp://<服务器>/
🔄 自动上传的触发点 上传由 update-index.ps1重建入口之后自动调用。因此无论手动运行脚本,还是双击 更新入口.bat,都会在刷新入口的同时完成上传。

03涉及文件

文件作用改动性质
upload-ftp.ps1 新增:用 curl.exe 遍历 *.html 逐个 FTP 上传;从 dsh 凭据文件读账号/密码。
(curl 会把中文文件名按 UTF-8 发送,避免服务器上文件名乱码)
新增
update-index.ps1 修改:重建入口页后自动调用 upload-ftp.ps1 修改
更新入口.bat 修改:双击入口,标题/文案更新为"更新 + 上传"。 修改
~/.dsh/.credentials.yaml 修改:新增 DSH_FTP_USER / DSH_FTP_PASS 两行(dsh 凭据文件)。 修改

04凭据安全方案

凭据存放在 dsh 自带的凭据文件~/.dsh/.credentials.yaml,与已有的 DEEPSEEK_API_KEY 同处),上传脚本运行时自动读取:

# ~/.dsh/.credentials.yaml
DEEPSEEK_API_KEY: ...
DSH_FTP_USER: 你的账号
DSH_FTP_PASS: 你的密码
🔐 为什么这样存
  • 不写脚本:凭据不出现源码/脚本里。
  • 不写注册表:不修改系统环境变量,不动电脑系统。
  • 不随站点上传:凭据在 ~/.dsh 下,与站点目录隔离。
  • 可兜底:环境变量 DSH_FTP_USER / DSH_FTP_PASS 可用作兜底;缺失时脚本报错并提示。

05配置项

来源默认 / 说明
hostdsh 凭据文件 / 环境变量 DSH_FTP_HOST<服务器地址·不公开>
portdsh 凭据文件 / 环境变量 DSH_FTP_PORT"21"(必须写成字符串,见下)
userdsh 凭据文件 / DSH_FTP_USER必填
passdsh 凭据文件 / DSH_FTP_PASS必填
远程目录环境变量 DSH_FTP_DIR空 = 根目录;可填 /sub

上传方式为覆盖式:已存在的文件也会重新上传,因此新增与修改都能同步到服务器。

06实测验证

✅ 验证结果无任何环境变量的情况下运行,脚本从 dsh 凭据文件读到账号/密码, 10 个 HTML 全部上传成功ftp://<服务器>/,包括 index.html 及各内容页。

07常见问题排查

上线初期遇到并已修复的三个问题,都藏在配置与编码细节里:

7.1 凭据值必须是字符串,且用 ASCII 引号

dsh 读取 ~/.dsh/.credentials.yaml 时要求每个值都必须是字符串 (源码 dsh-credentials-localtypeof value !== "string" 即抛错),空串也会报错。因此:

写法YAML 解析结果结果
DSH_FTP_PORT: "21"字符串 "21"✅ 正确
DSH_FTP_PORT: 21整数 21❌ dsh 报 must be a string
DSH_FTP_PORT: “21”字符串 "“21”"(弯引号被当普通字符)❌ 上传脚本 URL 乱码
⚠️ 弯引号的坑 从文档 / 微信 / Word 复制值进 yaml 时,容易带入中文弯引号 “”。YAML 不把它当引号语法,会当作 普通字符拼进字符串——dsh 类型检查能过(因为它确实是字符串),但上传脚本的 Trim('"') 剥不掉弯引号, 端口被读成 “21”,拼出 ftp://…:“21”/,curl 报 bad/illegal format。 所以务必用 ASCII 直引号"21")或直接不带引号但与字符串要求不冲突的值。

7.2 改脚本后要保持 UTF-8 BOM

Windows PowerShell 5.1 对无 BOM.ps1 按系统 ANSI(GBK)读取,中文会变乱码甚至 解析失败。脚本必须保存为带 BOM 的 UTF-8(首字节 EF BB BF)。用编辑器改动 upload-ftp.ps1 后,若它曾被去 BOM 保存,要用带 BOM 方式重新保存(可对照 update-index.ps1, 它始终带 BOM)。

7.3 排查思路

  • curl: (3) URL using bad/illegal format → 八成是 host / port 被弯引号污染,先看 upload-ftp.ps1 打印的 ftp://… 地址。
  • 启动 dsh 报 … must be a string → 凭据值写成了裸数字/布尔,加 ASCII 引号。
  • 脚本解析报"字符串缺少终止符 / 乱码" → BOM 丢了,用带 BOM UTF-8 重存。

08边界与注意事项

  • 远程目录默认根目录:若网站在服务器上的实际路径在子目录,需设置 DSH_FTP_DIR
  • 中文文件名按 UTF-8 上传:用 curl.exe 上传,文件名按 UTF-8 发送,中文文件名在服务器上不会乱码。 (FtpWebRequest 会按系统 ANSI/GBK 编码文件名,导致服务器上中文文件名乱码,因此不再使用。)
  • 只传 HTML:.md 源文件不在上传范围(按需求)。
  • 中文脚本需 UTF-8 BOM:Windows PowerShell 5.1 会按 GBK 读无 BOM 脚本导致乱码,脚本均保持带 BOM 的 UTF-8。
  • 凭据改动时机:改了 dsh 凭据文件后,下次运行上传脚本即生效。
  • 暂停上传:把 update-index.ps1 末尾调用 upload-ftp.ps1 的两行注释掉即可。

09延伸方向

🚧 可选增强 若想要网页 GUI 的 FTP 配置表单(在 dsh 设置界面直接填账号/密码保存),需要开发一个 Cordis 设置分节插件并在浏览器侧渲染。工作量和风险均大于当前方案;当前"凭据在 dsh 设置文件"的方式已满足 "受保护、不改系统"的要求,可先用。