From cbb847aed89f5452fdbd351968cc2b9c993d9f66 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 29 Oct 2026 20:34:06 +0800 Subject: [PATCH] Record approved cfn production release and verification --- docs/content/WRITING.md | 157 ++ .../content/tutorials/clash-meta-android.html | 1 + docs/content/tutorials/clash-meta-android.md | 103 + docs/content/tutorials/dns.html | 1 + docs/content/tutorials/dns.md | 143 ++ docs/content/tutorials/mac-client-guide.html | 1 + docs/content/tutorials/mac-client-guide.md | 57 + docs/content/tutorials/migration.html | 1 + docs/content/tutorials/migration.md | 78 + docs/content/tutorials/quantumult-x-ios.html | 1 + docs/content/tutorials/quantumult-x-ios.md | 99 + docs/content/tutorials/system-proxy-tun.html | 1 + docs/content/tutorials/system-proxy-tun.md | 103 + docs/content/tutorials/v2rayng-android.html | 1 + docs/content/tutorials/v2rayng-android.md | 98 + docs/content/tutorials/verge-linux.html | 1 + docs/content/tutorials/verge-linux.md | 101 + docs/content/tutorials/verge-mac.html | 1 + docs/content/tutorials/verge-mac.md | 80 + docs/content/tutorials/windows.html | 1 + docs/content/tutorials/windows.md | 93 + docs/maintenance/EDITORIAL_API.md | 161 ++ docs/maintenance/ILLUSTRATIONS.md | 65 + .../PREVIEW_VERIFICATION_2026-10-29.json | 1561 +++++++++++++++ .../PRODUCTION_VERIFICATION_2026-10-29.json | 1721 +++++++++++++++++ .../RELEASE_PREFLIGHT_2026-10-28.md | 124 ++ docs/maintenance/SEO_BASELINE_2026-10-22.json | 986 ++++++++++ docs/maintenance/SEO_PLAN.md | 734 +++++++ docs/maintenance/TUTORIALS.md | 184 ++ 29 files changed, 6658 insertions(+) create mode 100644 docs/content/WRITING.md create mode 100644 docs/content/tutorials/clash-meta-android.html create mode 100644 docs/content/tutorials/clash-meta-android.md create mode 100644 docs/content/tutorials/dns.html create mode 100644 docs/content/tutorials/dns.md create mode 100644 docs/content/tutorials/mac-client-guide.html create mode 100644 docs/content/tutorials/mac-client-guide.md create mode 100644 docs/content/tutorials/migration.html create mode 100644 docs/content/tutorials/migration.md create mode 100644 docs/content/tutorials/quantumult-x-ios.html create mode 100644 docs/content/tutorials/quantumult-x-ios.md create mode 100644 docs/content/tutorials/system-proxy-tun.html create mode 100644 docs/content/tutorials/system-proxy-tun.md create mode 100644 docs/content/tutorials/v2rayng-android.html create mode 100644 docs/content/tutorials/v2rayng-android.md create mode 100644 docs/content/tutorials/verge-linux.html create mode 100644 docs/content/tutorials/verge-linux.md create mode 100644 docs/content/tutorials/verge-mac.html create mode 100644 docs/content/tutorials/verge-mac.md create mode 100644 docs/content/tutorials/windows.html create mode 100644 docs/content/tutorials/windows.md create mode 100644 docs/maintenance/EDITORIAL_API.md create mode 100644 docs/maintenance/ILLUSTRATIONS.md create mode 100644 docs/maintenance/PREVIEW_VERIFICATION_2026-10-29.json create mode 100644 docs/maintenance/PRODUCTION_VERIFICATION_2026-10-29.json create mode 100644 docs/maintenance/RELEASE_PREFLIGHT_2026-10-28.md create mode 100644 docs/maintenance/SEO_BASELINE_2026-10-22.json create mode 100644 docs/maintenance/SEO_PLAN.md create mode 100644 docs/maintenance/TUTORIALS.md diff --git a/docs/content/WRITING.md b/docs/content/WRITING.md new file mode 100644 index 00000000..1463f0dd --- /dev/null +++ b/docs/content/WRITING.md @@ -0,0 +1,157 @@ +# AI 写作与文章关联索引 + +适用项目:FNA_V3。用户于2026-10-27指定本聊天持续为该项目写文章,并要求各 AI 写作时形成相关内容之间的跳转。**每次选题、撰写、重写、改名、移动、合并或撤下文章前,先读本文。** 本规则适用于项目中的后续 AI,不依赖某一聊天的上下文;不表示后台自动写作或自动发布。 + +发布已采用本站[独立文章 API](../maintenance/EDITORIAL_API.md),不经过ATOM。AI保留项目正文源,通过API保存冻结草稿、取得签名预览、发布确认的hash并核对回执;本索引仍由写作AI同任务维护,API不会自动改写它。 + +本文是写作流程、文章用途及文章关系的唯一维护入口。文章正文保存在各自源文件,数据库是页面实际读取的内容;栏目实现、渲染与备份方法见[教程维护](../maintenance/TUTORIALS.md),SEO项目状态见[SEO清单](../maintenance/SEO_PLAN.md)。不要在这些文档中再复制一份持续更新的文章关系表。 + +## 1 写作前先确定读者要完成的任务 + +- 入门教程:以第一次使用为前提,讲准备、下载、安装、配置、使用和基本排错。不要把客户端迁移作为普通入门教程的主线。 +- 下载与选型:讲适用平台、版本/架构、官方来源和选哪个安装包;引用官方发布入口,不把未经验证的第三方包当官方下载。 +- 综合教程(栏目原名“进阶教程”,URL仍为`/advanced`):讲具体机制、配置取舍、迁移或专项排错,并链接读者需要的基础操作。 +- 资源与时效内容:区分长期说明和当天资源状态。长期教程优先链接稳定说明/栏目,不依赖会过期的某一天资源页。 + +先查询下表和当前数据库,再决定重写已有文章还是新增。主题相同优先完善唯一正文;不同平台可以分别写,但需要实际的平台差异。标题、开头、步骤和关联链接都应服务于同一个任务。 + +本站是公开分享免费节点的站点。入门教程优先按“从本站获取适用格式的免费订阅→导入→选择节点→验证”的实际过程组织;公开分享的订阅与私人账户订阅需要区分,不把私人账户保密提醒套进免费资源步骤。相关说明和内链自然放在读者需要的位置,避免堆叠与场景无关的提示框。 + +正文直接进入引言,不再添加“入门教程 · Android · 更新于……”这类顶部信息行;分类、平台和日期不要在正文开头重复网站信息栏。必要的官方参考链接可保留在文末,内部核验过程另存维护记录。 + +**禁止在公开文章中写内部核验与验收说明。** 用户于2026-10-27明确要求:以后文章里不再出现“本文的核对范围”“已核对官方文档”“未实测”“未进行真机联网测试”“未修改本机网络”等内容,也不换成同义的提示框、脚注或免责声明。核验范围、设备测试情况、开发验收过程及本地/上线状态只写入项目维护记录,不进入正文、摘要、图注或封面。 + +公开内容保留对读者有用的操作步骤、版本兼容条件、配置限制和参考来源;不得编造实测结论。发布前检查全文,发现上述内部说明必须删除或移入维护记录,不能指望上线流程自动去掉。“本页旧文”“沿用原地址更新内容”“核对本文时”等编辑历史和核验口吻同样移入维护记录;版本信息直接写适用版本、系统要求或示例版本。参考链接优先选读者实际需要的下载、配置与使用文档,不堆放仅用于编辑取证的界面实现源码。 + +自然、准确地表达;必要时用真实操作图、流程图、配置示例。软件版本、下载入口与兼容要求使用当次核对的官方来源;来源核验、页面检查和设备实测分别记录,未做实测不写“实测”。 + +### AI 新文章的点赞参数(2026-10-29) + +后续AI通过本站独立文章API**新建文章**时使用以下默认设置,由API在保存草稿时为每篇独立取值并冻结;相同请求重试、查询预览及发布不重新抽取。重写、接管、回退已有文章不重置原参数、点赞数或已完成进度,不自动给现有文章批量补额度。 + +| 设置 | 默认值 | 含义 | +| --- | --- | --- | +| `i7like`,API `like_settings.seven_day` | 随机整数5~35,含端点 | 原有短期待增加额度,随原任务逐次扣减 | +| `i365like`,API `like_settings.yearly` | 固定50 | 保留原持续年度随机机制:每天以50/365概率加1,长期平均每年约50赞,并非每年保证恰好50,不随一年结束停止 | +| `iYearLikeTarget`,API `like_settings.one_year` | 随机整数100~500,含端点 | 新增一次性年度额度;设200表示独立累计自动增加200赞,不是总点赞数封顶200 | + +一次性年度额度从正式发布时开始,按实际经过时间在一个日历年内分散增加,`iYearLikeAdded`记录已增加数量,`sYearLikeStartedAt`记录开始时间;满额后该项停止,`i365like`持续增长和真实点赞继续独立计算。任务停机造成的欠额在恢复后补至应有进度;满一年后首次恢复会补完余额,不能在调度停机时凭空执行。 + +新文章可省略`like_settings`使用上述默认值,也可在创建草稿时显式提交`{"seven_day":12,"yearly":50,"one_year":200}`;0表示关闭对应机制。保存后检查草稿响应的`like_settings`,发布后从鉴权的`source-articles/{id}`响应`like_growth`回读确认。旧文章编辑不传此对象;API拒绝通过普通改稿重置额度。设置与进度只属于内部发布数据,不写进公开正文、摘要、图注或封面。 + +具体字段、迁移、任务、测试与回退见[文章自动点赞维护](../maintenance/ARTICLE_LIKES.md)。这些默认值已落到本地代码及迁移,不代表已启用本机调度或已部署线上。 + +## 2 当前文章登记 + +核对日期:2026-10-28;证据为本机 `fna_v3` 数据库及已有正文源。表中 `iStatus=1` 只代表本地应用可显示,**不代表已经发布到生产**。十篇长期教程均已新建或重写并在本地确认;原七篇旧教程已处理完毕,仍不据此判断生产站现状。 + +ID用于核对本地行,站内链接使用已确认路径。跨环境迁移后重新核对ID,不能假定生产ID相同。 + +| 内容键 | 本地ID / 栏目 | 标题 | 实际路径 | 正文源 / 编辑状态 | 用途与引用边界 | +| --- | --- | --- | --- | --- | --- | +| verge-windows-start | 362 / Windows(入门) | Clash Verge Rev 使用教程:从安装到第一次连接(Windows) | `/a/clash-verge-rev-windows.html` | [windows.md](tutorials/windows.md);本地API版本4 | Windows新用户操作入口;下载段落锚点为 `#install` | +| cfw-to-verge | 212 / 综合教程 | 从 Clash for Windows 迁移到 Clash Verge Rev | `/a/m167.html` | [migration.md](tutorials/migration.md);本地API版本5 | 保留旧配置并更换客户端;不作为纯入门入口 | +| mihomo-dns | 361 / 综合教程 | Clash 进阶:DNS 防泄漏配置与验证 | `/a/mihomo-dns-leak.html` | [dns.md](tutorials/dns.md);本地API版本6 | Mihomo桌面DNS专题,含配置片段与验证方法 | +| cfa-android-legacy | 206 / Android(数据库名Andorid) | Clash Meta for Android 使用教程:导入订阅、选择节点与连接 | `/a/m169.html` | [clash-meta-android.md](tutorials/clash-meta-android.md);本地API版本6 | Android Clash配置入门;`#install` 安装、`#import` 导入;按MetaCubeX v2.11.36核对,保留原键和URL | +| quantumult-ios-legacy | 207 / iOS(数据库名Ios) | Quantumult X 使用教程:iOS 安装、订阅导入与连接 | `/a/m170.html` | [quantumult-x-ios.md](tutorials/quantumult-x-ios.md);本地API版本5 | iPhone/iPad入门;区分原生资源与本站通用订阅,#parser 解释第三方资源解析器,#import 导入;无真机实测 | +| v2rayng-android-legacy | 208 / Android(数据库名Andorid) | v2rayNG 使用教程:Android 安装、导入订阅与连接 | `/a/m171.html` | [v2rayng-android.md](tutorials/v2rayng-android.md);本地API版本7 | Android入门;`#install` 下载、`#import` 订阅导入;保留既有内容键和URL | +| clashx-mac-legacy | 209 / Mac | Mac 代理客户端下载指南:ClashX 与 Clash Verge Rev 怎么选 | `/a/m172.html` | [mac-client-guide.md](tutorials/mac-client-guide.md);本地API版本5 | Mac选型与官方下载;#download 核对系统与芯片,链接实际安装教程;旧ClashX原入口不可核验不等于所有分支失效 | +| cfw-mac-legacy | 210 / Mac | Clash Verge Rev 使用教程:Mac 安装、订阅与系统代理 | `/a/m173.html` | [verge-mac.md](tutorials/verge-mac.md);本地API版本2 | Mac操作入口;#install DMG安装,#import 订阅,系统代理与退出排错;无设备联网实测 | +| cfw-linux-legacy | 211 / Linux | Clash Verge Rev 使用教程:Linux 安装、订阅与代理设置 | `/a/m174.html` | [verge-linux.md](tutorials/verge-linux.md);本地API版本5 | Linux桌面入门;#install 包格式与架构,#import 订阅,#terminal 单条curl代理验证;不适用于无桌面的服务器 | +| system-proxy-vs-tun | 365 / 综合教程 | 系统代理和 TUN 有什么区别?接管范围、使用选择与排错 | `/a/system-proxy-vs-tun.html` | [system-proxy-tun.md](tutorials/system-proxy-tun.md);本地API版本1 | 桌面代理接管与出口选择;`#choose` 场景选择、`#switch` 切换检查、`#troubleshoot` 排错;三张流程图 | + +这里只登记长期编辑内容及值得复用的稳定资源说明,不逐条收录日更节点或账号文章。稳定入口为 `/freenode`(公开免费节点)、`/client`(入门)、`/advanced`(综合教程);平台入口和名称修改另按项目路由核对,不从名称自行拼接。 + +2026-10-29部署边界更新:上表10篇已通过本站API迁移到独立test并经用户确认后切到正式cfn,旧URL保留;生产发布以预览实际正文冻结再发布,未用test整库覆盖。test和生产的临时编辑密钥均在迁移后删除,接口默认关闭;后续本地写作继续使用本地API,正式编辑按明确任务与生产绑定启用。实际部署及验收统一见[发布记录](../maintenance/RELEASE_PREFLIGHT_2026-10-28.md#正式切换2026-10-29),上表ID仍为本地ID。 + +## 3 已有文章关系 + +以下为2026-10-28从本地数据库正文提取并核对源文件的**实际内链**,不是建议列表。箭头表示正文中有从来源到目标的链接;入向关系从本表反查,不另存一份容易失步的反向清单。 + +| 来源内容键 | 目标内容键 | 读者为什么跳转 / 放置位置 | 状态 | +| --- | --- | --- | --- | +| verge-windows-start | 栏目 `/freenode` | 导入前获取Clash订阅,以及节点失效后查看较新的分享 | 已在本地正文实现 | +| verge-windows-start | mihomo-dns | 入门完成后学习DNS路径;文末“下一步” | 已在本地正文实现 | +| mihomo-dns | verge-windows-start | 尚未安装客户端的读者回到Windows入门;文末说明 | 已在本地正文实现 | +| cfw-to-verge | 栏目 `/freenode` | 迁移时获取Clash/Mihomo免费订阅;保留旧订阅重新导入的选项 | 已在本地正文实现 | +| cfw-to-verge | mihomo-dns | 完成迁移后检查DNS路径;文末“下一步” | 已在本地正文实现 | +| v2rayng-android-legacy | 栏目 `/freenode` | 获取v2ray订阅、整批失效后寻找较新分享 | 已在本地正文实现 | +| v2rayng-android-legacy | verge-windows-start `#install` | 日常使用段落后,供同时需要Windows客户端的读者继续 | 已在本地正文实现 | +| v2rayng-android-legacy | cfa-android-legacy `#import` | 获取订阅段落说明Clash格式的Android导入入口 | 已在本地正文实现 | +| cfa-android-legacy | v2rayng-android-legacy `#import` | 导入前说明v2ray订阅和单节点分享链接的另一客户端用法 | 已在本地正文实现 | +| cfa-android-legacy | 栏目 `/freenode` | 获取Clash订阅,旧批次失效后寻找较新分享 | 已在本地正文实现 | +| cfa-android-legacy | verge-windows-start `#install` | 日常使用末尾提供Windows客户端安装入口 | 已在本地正文实现 | +| quantumult-ios-legacy | 栏目 `/freenode` | 选择较新的免费订阅;明确本站通用订阅需要格式适配 | 已在本地正文实现 | +| quantumult-ios-legacy | clashx-mac-legacy `#download` | 日常使用后提供Mac客户端选择入口,说明配置不可直接通用 | 已在本地正文实现 | +| clashx-mac-legacy | cfw-mac-legacy `#install` / `#import` | 选好客户端下载后进入Mac安装和连接步骤 | 已在本地正文实现 | +| clashx-mac-legacy | 栏目 `/freenode` | 选定客户端后获取Clash/Mihomo订阅 | 已在本地正文实现 | +| clashx-mac-legacy | verge-windows-start | 同时使用Windows时转到对应平台教程 | 已在本地正文实现 | +| clashx-mac-legacy | cfw-linux-legacy | 同时使用Linux桌面时转到对应平台教程 | 已在本地正文实现 | +| cfw-mac-legacy | clashx-mac-legacy `#download` | 安装前核对Mac系统和CPU架构 | 已在本地正文实现 | +| cfw-mac-legacy | 栏目 `/freenode` | 导入前选择Clash/Mihomo免费订阅 | 已在本地正文实现 | +| cfw-mac-legacy | mihomo-dns | 基本连接完成后深入检查DNS路径 | 已在本地正文实现 | +| cfw-linux-legacy | 栏目 `/freenode` | 导入Clash/Mihomo订阅和更新失效批次 | 已在本地正文实现 | +| cfw-linux-legacy | mihomo-dns | Linux基本连接后继续学习DNS与TUN验证 | 已在本地正文实现 | +| cfw-linux-legacy | clashx-mac-legacy `#download` | 需要Mac客户端时进入对应下载指南 | 已在本地正文实现 | +| verge-windows-start | system-proxy-vs-tun `#choose` | “需要一开始就开 TUN 吗”后提供接管方式选择入口 | 已在本地正文实现 | +| mihomo-dns | system-proxy-vs-tun `#tun` | TUN/DNS 配置片段前解释接管机制 | 已在本地正文实现 | +| system-proxy-vs-tun | verge-windows-start `#enable` | 切换前完成 Windows 基本连接 | 已在本地正文实现 | +| system-proxy-vs-tun | cfw-mac-legacy `#enable` | 切换前完成 Mac 基本连接 | 已在本地正文实现 | +| system-proxy-vs-tun | cfw-linux-legacy `#connect` / `#terminal` | Linux 基础连接及单条命令显式代理 | 已在本地正文实现 | +| system-proxy-vs-tun | mihomo-dns `#dns-2` | 继续检查 DNS 接管、加密和出口 | 已在本地正文实现 | + +两篇Android教程通过订阅格式段落互链;Mac下载指南与操作教程互链,Linux从下载指南和真实Linux栏目获得入口,iOS沿用真实iOS栏目入口。系统代理与TUN专题由Windows和DNS正文提供入口,并指向三平台的基础操作及DNS专题。目录、标签、导航和热门榜不算正文关联;正文内链及锚点已经本地HTTP验证。 + +## 4 怎样安排链接 + +| 关系 | 典型写法与放置位置 | 目标选择 | +| --- | --- | --- | +| 前置准备 | “尚未安装客户端,先完成……”放在需要操作之前 | 对应平台的安装/下载/入门文章 | +| 具体操作 | “订阅导入步骤见……”放在提到该操作的位置 | 对应教程的具体段落锚点 | +| 解释概念 | “关于系统代理与TUN的区别……”放在需要解释处 | 已完成、平台适用的专题文章 | +| 解决故障 | 在具体错误或现象后提供排查入口 | 对应问题的排错文章 | +| 继续学习 | 完成当前任务后的下一步,放在文末 | 与当前任务相邻的进阶内容 | +| 返回基础 | 进阶内容给尚未具备前置条件的读者一个入口 | 基础教程;不强迫已经会用的读者重复阅读 | + +### 下载文章的具体例子 + +**Mac已建立独立选型与下载指南**,可链接 `/a/m172.html#download`,其中也提供Mac安装与导入教程的入口。Windows当前可用目标仍是入门教程中的下载段落: + +```html +Clash Verge Rev Windows 下载与安装步骤 +``` + +例如,后续撰写某篇进阶配置教程,读者需要先安装该客户端,就可在前置准备处使用这个入口。如果以后建立其他平台的独立下载文章:先创建并验证真实URL,登记用途与状态,再把适用教程中的下载链接改到新文;同时在下载文章中提供“下载后如何使用”的入门链接。不要提前创造一个不存在的下载URL,也不要把本段示例当作当前正文已经增加的链接。 + +### 链接质量约束 + +- 按读者需要建立方向,不要求任意两篇都互链。新增文章应检查“从哪里能找到它”,在确有相关性的旧文中补入口;若没有合适旧文,明确使用真实栏目入口并记录原因,不硬塞链接。 +- 使用描述目标任务的锚文本,例如“Windows 订阅导入步骤”;少用无意义的“点击这里”,不重复堆砌关键词,不设固定链接数量指标。 +- 站内文章使用根相对路径 `/a/实际slug.html`,不要写本机 `.loc` 或未经确认的生产域名。锚点必须真实存在;平台不适用时说清范围,不把Windows教程当作所有平台通用操作。 +- 正文相关位置优先,文末“下一步”只保留有用内容,不把每篇文章都变成全站链接目录。 +- 待写、撤下、未核验或已过时的文章不能包装成可靠的当前操作入口。需要引用历史内容时,明确历史用途和限制。 +- 改名或移动分类优先保留原slug。确需改URL/合并/撤下时,先查本表入向关系及源文件/数据库中的实际链接,再处理所有受影响正文和已授权范围内的重定向;只改索引不算修复完成。 +- 不把“未来关联”记为“已实现”。对公开文章,不发布指向仅本地存在页面的内链;上线时核对目标与来源是否一同部署。 + +## 5 每次写作的固定流程 + +1. **查现状。** 读AGENTS和本文,按主题/平台搜索登记表,再查当前数据库标题、slug、栏目、发布状态和正文。阅读拟链接文章,不能只凭标题判断合适。 +2. **确定位置。** 明确本文解决什么、读者需要什么前置知识、完成后下一步是什么。挑选现有有效目标;缺少的内容登记为待办,不自动扩大成一批新文章。 +3. **写正文。** 遵守第1节公开内容要求,禁止写核对范围、未实测等内部说明;发布前检查正文、摘要、图注和封面。在合适段落放入自然的站内链接,并保留必要官方来源。新文确定slug前查重。首次重写仅在数据库中的旧文时,先备份,再建立项目正文源。 +4. **补相关旧文。** 在本次获准写作范围内,同步维护直接相关的少量链接,保留无关正文和并行修改;不借机全站重写、修改资源数据或上线。新文只有草稿时先登记计划,等目标可用后再启用链接。 +5. **保存与同步。** 按[独立文章API](../maintenance/EDITORIAL_API.md)提交完整草稿批次,预览确认后发布指定hash并查询回执;不手工绕过版本控制更新文章表。首次接管旧文显式绑定准确ID。项目正文源与本文的文章行、实际关系行同任务维护;草稿、公开正文、搜索同步和生产部署分别确认,避免源文件有链接而网页没有。 +6. **验收链接。** 检查来源正文是否实际含链接、目标标题/栏目/平台是否匹配、HTTP是否成功及锚点是否存在;不能只看200(项目路由可能接受错误前缀)。检查移动排版和配图;访问线上仍按项目授权边界,不能以验链接为由越界。 +7. **收尾说明。** 报告改了哪些文章、增加/修复了哪些关联、哪些仅在本地生效、是否同步搜索及是否发布。未完成的关系保留明确原因与下一步。备份和操作过程留维护记录,不向本索引堆聊天流水。 + +## 6 登记规则与待补内容 + +新增登记项使用稳定内容键,字段沿用第2节:本地ID、栏目、准确标题、真实路径、正文源、编辑/环境状态、读者任务与适用限制。标题变化不必更换内容键。关系沿用第3节:来源键、目标键、理由/位置、实际状态;有段落链接时同时记录锚点。填写核对日期和证据范围,禁止把“已有记录”写成“刚刚实测”。 + +当前待补(选题储备,**尚未创建文章,也不自动授权逐篇执行**): + +| 主题 | 当前可用替代入口 | 处理条件 | +| --- | --- | --- | +| 其他平台独立下载/选型文章 | Mac已有 `/a/m172.html#download`;Windows入门 `#install` | 下载信息确有独立维护需要时再建立;与入门教程互相提供自然入口 | +| 订阅导入失败排查 | Windows入门的导入与常见问题段落 | 积累明确错误场景后再拆专题,避免重复原文 | + +本次建立的是AI协作约定和已核实的关联索引,不是自动推荐程序、链接注入脚本或定时任务。正文关系变动时由执行写作的AI同任务更新本文。 diff --git a/docs/content/tutorials/clash-meta-android.html b/docs/content/tutorials/clash-meta-android.html new file mode 100644 index 00000000..184b3400 --- /dev/null +++ b/docs/content/tutorials/clash-meta-android.html @@ -0,0 +1 @@ +

在 Android 手机上使用本站的 Clash 订阅,可以通过 Clash Meta for Android 完成。它会读取订阅中的节点和分流规则,让你在手机上选择线路、更新配置,并决定哪些连接通过代理。

以下使用 MetaCubeX 项目发布的 Clash Meta for Android,依次完成安装、订阅导入和首次连接。

先分清三个对象
配置整份节点和规则清单
→
代理组决定某类连接怎么走
→
节点实际连接的一条线路
图 1 · 一份配置可以包含多个代理组,每个组又可以选择节点或其他策略。导入配置后,还要检查组内选择。

01 从官方发行页下载安装

打开 Clash Meta for Android 官方发行页,展开 Assets,选择适合手机的 .apk 安装包。初次使用选择正式发行版;后续升级也可使用这个官方入口。

设备情况安装包文件名中的架构
近几年常见的 Android 手机arm64-v8a
不确定设备架构universal,通用包体积较大
已确认是 32 位 ARM 的旧设备armeabi-v7a
x86 架构设备或模拟器按实际架构选择 x86 / x86_64

例如,v2.11.36 的常见手机安装包为 cmfa-2.11.36-meta-arm64-v8a-release.apk。以后版本号会变化,不必为了和示例一致而寻找旧版。

下载完成后打开 APK,按系统提示安装。如果手机要求允许浏览器或文件管理器安装应用,按提示为本次安装授权。官方项目说明最低要求 Android 5.0,推荐 Android 7.0 及以上;具体设备能否正常使用,还要看系统与安装包是否兼容。

02 导入本站的 Clash / Mihomo 订阅

进入本站免费节点页面,打开较新的一篇分享,复制标明 Clash / Mihomo 的订阅链接。这里需要的是能返回配置的地址,不是那篇文章的网页地址。

如果手里拿到的是 v2ray 订阅,或 vmess://、vless:// 等单独节点链接,可以按 v2rayNG 的导入步骤使用;本篇直接使用本站提供的 Clash / Mihomo 配置。

  1. 打开 Clash Meta for Android,进入 配置。
  2. 点击添加按钮,选择 从 URL 导入。
  3. 填写配置名称,例如“本站免费节点”,再把订阅链接粘贴到 URL。
  4. 点击保存,等待配置下载和校验完成。
  5. 返回配置列表,点选刚保存的配置,将它设为当前配置。
  6. 回到首页,确认“配置”一栏显示的是刚才填写的名称。

这里的“保存”会尝试获取配置内容。如果下载或校验报错,要先解决这一步;只填写了名称和地址、随后返回列表,并不代表已经导入成功。

配置出现了,为什么还不能连接?
保存成功已下载并读取配置
→
选为当前配置告诉客户端使用哪一份
→
启动并选线路让实际访问通过节点
图 2 · 操作阶段示意,并非软件截图。“保存”“选中”“启动”分别完成不同的事情。

如果你已经下载了完整的 Clash YAML 配置文件,也可以在添加配置时选择 从文件导入。本地文件适合手动导入;需要定期获取分享更新时,URL 订阅更方便。

03 回到首页,启动代理服务

确认当前配置已选中后,点击首页的 点此启动。首次运行通常会出现 Android 的 VPN 连接请求,确认应用名称后允许。

客户端利用 Android VPN 接口接管流量,通常不需要 Root。启动后,首页会显示运行状态;系统也可能显示 VPN 标识或常驻通知。

如果 v2rayNG、其他 VPN 或使用本地 VPN 的过滤工具正在运行,先停止它们,再启动 Clash Meta。同一个 Android 用户空间只能有一个活动 VPN 服务,两个应用轮流启动会相互影响。

先保持默认网络设置完成首次连接。桌面教程中的“系统代理开关”不能直接照搬到这里,Android 的主要入口是当前客户端的 VPN 服务。

04 选择规则模式,再选一条节点

进入 代理 页面,找到模式选项,先使用 规则模式。然后找到负责普通代理流量的代理组,在可以手动选择的组里点选一个节点。

代理组名称由订阅决定,可能叫“节点选择”“代理”“Proxy”,也可能使用其他名称。遇到一组套着另一组的情况,可以沿当前选项继续查看,直到确认实际使用的是哪条节点或策略。

选项对连接的影响
规则模式按当前配置的规则分流,适合先完成日常连接
全局模式通常将进入内核的业务连接交给全局策略组;仍需检查该组选项
直连模式 / DIRECT直接连接目标,不经过代理节点
手动选择组由你指定组内的一项,适合初次确认线路
自动选择组由配置的测试和选择策略决定线路,不一定允许手动指定

如果页面提供延迟测试,可以先运行一次,避开一直超时的节点。低延迟只代表对测试目标的结果,最终仍以你要访问的网站是否可用为准。

规则模式不等于“所有网站都走代理”。国内网站或局域网地址按规则直连是常见配置,具体行为取决于你导入的规则。

05 用实际访问检查连接

保持服务运行,打开浏览器访问你需要使用的网站,再试一下对应应用。首次验证时,重新加载网页,避免把缓存中的旧页面当成连接成功。

如果无法打开,按顺序检查:首页是否在运行 → 当前配置是否正确 → 模式是否合适 → 代理组是否选到可用节点。 都确认后,再更换一条节点重试。

VPN 标识表示接管服务已经建立,不保证远端节点可用;延迟测试成功也不代表所有服务都能访问。先完成一个实际使用场景,比一开始调整大量高级参数更容易定位问题。

06 更新配置、换节点和停止使用

更新节点列表: 在“配置”中找到这份 URL 配置,使用其更新操作;需要同时刷新多份配置时,可以使用“更新全部”。更新之后再到代理页检查当前选项,因为新配置可能调整节点或组名。

旧地址里已经没有可用节点: 回到免费节点页面查看较新的分享。本站不同日期可能使用不同订阅地址,更新旧 URL 不会自动寻找下一期;需要时编辑配置中的 URL,换成新地址并保存,再确认它仍是当前配置。

切换节点: 在代理页调整对应手动选择组,再重新发起网页或应用请求。已经建立的长连接可能继续使用原线路,验证时可以重新连接该应用。

暂停使用: 在首页点击运行状态区域停止服务,并确认运行状态结束。仅返回桌面并不等于停止代理。

如果还要在电脑上使用本站的 Clash 订阅,可以继续阅读 Clash Verge Rev Windows 入门教程。订阅格式相近,但安装方式和系统接管入口不同,按对应平台操作即可。

07 常见问题

提示“没有选择配置文件”。 返回配置列表,确认配置已经保存成功,再点选它。查看首页显示的配置名称,避免只完成添加却没有启用。

保存时报下载失败或解析失败。 先核对 URL 是否完整、是否复制成文章地址,以及格式是否为 Clash / Mihomo。链接失效、返回网页而非配置,或者网络无法访问该地址,都可能导致导入失败;先尝试较新的适用订阅,不必急着重装软件。

配置导入成功,代理页却没有预期节点。 先核对首页当前配置;若配置引用了外部节点资源,还要检查那些资源是否下载成功。列表名称和分组由配置决定,换了订阅后未必与教程示例一致。

延迟正常,但某个应用无法连接。 如果修改过访问控制,检查该应用是否在预期接管范围内;再检查它可能匹配的代理组,并尝试另一条节点。只测试一个地址,无法判断所有应用的访问情况。

锁屏后过一会儿断开。 先观察客户端服务是否已被系统结束。如果确实被结束,再到手机的电池或后台应用管理中允许它后台运行。若服务仍在,优先检查网络变化和节点可用性。

diff --git a/docs/content/tutorials/clash-meta-android.md b/docs/content/tutorials/clash-meta-android.md new file mode 100644 index 00000000..c4604c34 --- /dev/null +++ b/docs/content/tutorials/clash-meta-android.md @@ -0,0 +1,103 @@ +在 Android 手机上使用本站的 Clash 订阅,可以通过 **Clash Meta for Android** 完成。它会读取订阅中的节点和分流规则,让你在手机上选择线路、更新配置,并决定哪些连接通过代理。 + +以下使用 MetaCubeX 项目发布的 Clash Meta for Android,依次完成安装、订阅导入和首次连接。 + +
先分清三个对象
配置整份节点和规则清单
→
代理组决定某类连接怎么走
→
节点实际连接的一条线路
图 1 · 一份配置可以包含多个代理组,每个组又可以选择节点或其他策略。导入配置后,还要检查组内选择。
+ + + +

01 从官方发行页下载安装

+ +打开 [Clash Meta for Android 官方发行页](https://github.com/MetaCubeX/ClashMetaForAndroid/releases/latest),展开 **Assets**,选择适合手机的 `.apk` 安装包。初次使用选择正式发行版;后续升级也可使用这个官方入口。 + +| 设备情况 | 安装包文件名中的架构 | +|---|---| +| 近几年常见的 Android 手机 | `arm64-v8a` | +| 不确定设备架构 | `universal`,通用包体积较大 | +| 已确认是 32 位 ARM 的旧设备 | `armeabi-v7a` | +| x86 架构设备或模拟器 | 按实际架构选择 `x86` / `x86_64` | + +例如,v2.11.36 的常见手机安装包为 `cmfa-2.11.36-meta-arm64-v8a-release.apk`。以后版本号会变化,不必为了和示例一致而寻找旧版。 + +下载完成后打开 APK,按系统提示安装。如果手机要求允许浏览器或文件管理器安装应用,按提示为本次安装授权。官方项目说明最低要求 Android 5.0,推荐 Android 7.0 及以上;具体设备能否正常使用,还要看系统与安装包是否兼容。 + +

02 导入本站的 Clash / Mihomo 订阅

+ +进入本站[免费节点页面](/freenode),打开较新的一篇分享,复制标明 **Clash / Mihomo** 的订阅链接。这里需要的是能返回配置的地址,不是那篇文章的网页地址。 + +如果手里拿到的是 v2ray 订阅,或 `vmess://`、`vless://` 等单独节点链接,可以按 [v2rayNG 的导入步骤](/a/m171.html#import)使用;本篇直接使用本站提供的 Clash / Mihomo 配置。 + +1. 打开 Clash Meta for Android,进入 **配置**。 +2. 点击添加按钮,选择 **从 URL 导入**。 +3. 填写配置名称,例如“本站免费节点”,再把订阅链接粘贴到 **URL**。 +4. 点击保存,等待配置下载和校验完成。 +5. 返回配置列表,点选刚保存的配置,将它设为当前配置。 +6. 回到首页,确认“配置”一栏显示的是刚才填写的名称。 + +这里的“保存”会尝试获取配置内容。如果下载或校验报错,要先解决这一步;只填写了名称和地址、随后返回列表,并不代表已经导入成功。 + +
配置出现了,为什么还不能连接?
保存成功已下载并读取配置
→
选为当前配置告诉客户端使用哪一份
→
启动并选线路让实际访问通过节点
图 2 · 操作阶段示意,并非软件截图。“保存”“选中”“启动”分别完成不同的事情。
+ +如果你已经下载了完整的 Clash YAML 配置文件,也可以在添加配置时选择 **从文件导入**。本地文件适合手动导入;需要定期获取分享更新时,URL 订阅更方便。 + +

03 回到首页,启动代理服务

+ +确认当前配置已选中后,点击首页的 **点此启动**。首次运行通常会出现 Android 的 VPN 连接请求,确认应用名称后允许。 + +客户端利用 Android VPN 接口接管流量,通常不需要 Root。启动后,首页会显示运行状态;系统也可能显示 VPN 标识或常驻通知。 + +如果 v2rayNG、其他 VPN 或使用本地 VPN 的过滤工具正在运行,先停止它们,再启动 Clash Meta。同一个 Android 用户空间只能有一个活动 VPN 服务,两个应用轮流启动会相互影响。 + +先保持默认网络设置完成首次连接。桌面教程中的“系统代理开关”不能直接照搬到这里,Android 的主要入口是当前客户端的 VPN 服务。 + +

04 选择规则模式,再选一条节点

+ +进入 **代理** 页面,找到模式选项,先使用 **规则模式**。然后找到负责普通代理流量的代理组,在可以手动选择的组里点选一个节点。 + +代理组名称由订阅决定,可能叫“节点选择”“代理”“Proxy”,也可能使用其他名称。遇到一组套着另一组的情况,可以沿当前选项继续查看,直到确认实际使用的是哪条节点或策略。 + +| 选项 | 对连接的影响 | +|---|---| +| 规则模式 | 按当前配置的规则分流,适合先完成日常连接 | +| 全局模式 | 通常将进入内核的业务连接交给全局策略组;仍需检查该组选项 | +| 直连模式 / DIRECT | 直接连接目标,不经过代理节点 | +| 手动选择组 | 由你指定组内的一项,适合初次确认线路 | +| 自动选择组 | 由配置的测试和选择策略决定线路,不一定允许手动指定 | + +如果页面提供延迟测试,可以先运行一次,避开一直超时的节点。低延迟只代表对测试目标的结果,最终仍以你要访问的网站是否可用为准。 + +规则模式不等于“所有网站都走代理”。国内网站或局域网地址按规则直连是常见配置,具体行为取决于你导入的规则。 + +

05 用实际访问检查连接

+ +保持服务运行,打开浏览器访问你需要使用的网站,再试一下对应应用。首次验证时,重新加载网页,避免把缓存中的旧页面当成连接成功。 + +如果无法打开,按顺序检查:**首页是否在运行 → 当前配置是否正确 → 模式是否合适 → 代理组是否选到可用节点。** 都确认后,再更换一条节点重试。 + +VPN 标识表示接管服务已经建立,不保证远端节点可用;延迟测试成功也不代表所有服务都能访问。先完成一个实际使用场景,比一开始调整大量高级参数更容易定位问题。 + +

06 更新配置、换节点和停止使用

+ +**更新节点列表:** 在“配置”中找到这份 URL 配置,使用其更新操作;需要同时刷新多份配置时,可以使用“更新全部”。更新之后再到代理页检查当前选项,因为新配置可能调整节点或组名。 + +**旧地址里已经没有可用节点:** 回到[免费节点页面](/freenode)查看较新的分享。本站不同日期可能使用不同订阅地址,更新旧 URL 不会自动寻找下一期;需要时编辑配置中的 URL,换成新地址并保存,再确认它仍是当前配置。 + +**切换节点:** 在代理页调整对应手动选择组,再重新发起网页或应用请求。已经建立的长连接可能继续使用原线路,验证时可以重新连接该应用。 + +**暂停使用:** 在首页点击运行状态区域停止服务,并确认运行状态结束。仅返回桌面并不等于停止代理。 + +如果还要在电脑上使用本站的 Clash 订阅,可以继续阅读 [Clash Verge Rev Windows 入门教程](/a/clash-verge-rev-windows.html#install)。订阅格式相近,但安装方式和系统接管入口不同,按对应平台操作即可。 + +

07 常见问题

+ +**提示“没有选择配置文件”。** 返回配置列表,确认配置已经保存成功,再点选它。查看首页显示的配置名称,避免只完成添加却没有启用。 + +**保存时报下载失败或解析失败。** 先核对 URL 是否完整、是否复制成文章地址,以及格式是否为 Clash / Mihomo。链接失效、返回网页而非配置,或者网络无法访问该地址,都可能导致导入失败;先尝试较新的适用订阅,不必急着重装软件。 + +**配置导入成功,代理页却没有预期节点。** 先核对首页当前配置;若配置引用了外部节点资源,还要检查那些资源是否下载成功。列表名称和分组由配置决定,换了订阅后未必与教程示例一致。 + +**延迟正常,但某个应用无法连接。** 如果修改过访问控制,检查该应用是否在预期接管范围内;再检查它可能匹配的代理组,并尝试另一条节点。只测试一个地址,无法判断所有应用的访问情况。 + +**锁屏后过一会儿断开。** 先观察客户端服务是否已被系统结束。如果确实被结束,再到手机的电池或后台应用管理中允许它后台运行。若服务仍在,优先检查网络变化和节点可用性。 + +
参考资料:官方 v2.11.36 发行页、项目说明、Android 官方文档。
diff --git a/docs/content/tutorials/dns.html b/docs/content/tutorials/dns.html new file mode 100644 index 00000000..a7885f56 --- /dev/null +++ b/docs/content/tutorials/dns.html @@ -0,0 +1 @@ +

使用 Clash 时,代理连接正常、出口 IP 符合预期,只能说明部分网络请求已经经过代理。DNS 查询是否沿着预期路径发送,还需要单独确认。

这也是 DNS 防泄漏配置的重点:明确哪些查询由客户端处理,哪些交给远端节点解析,以及查询经过什么连接抵达解析服务。

本文面向采用 Mihomo 内核的桌面客户端,从解析路径出发,介绍一套可检查、可验证的配置方法。使用配置示例前,先确认客户端所用内核支持相应字段。

01 识别两条不同的路径

DNS 泄漏通常发生在流量路径分离的地方。 应用访问网站前,可能先通过系统 DNS 查询域名。如果网页连接进入代理,而查询仍发送给本地路由器或运营商,两类请求就走了不同的路径。

图 1 · 网页走代理,查询可能走另一条路
应用发起请求
Mihomo接管网页连接
代理节点连接目标网站
另一路:应用 → 系统 DNS → 路由器 / 运营商
如果 DNS 查询没有按预期接管,网页出口正常仍可能伴随解析绕行。

普通 DNS 查询通常以明文传输,沿途网络可以观察其中的域名。这类查询主要暴露“访问了哪个域名”,通常不包含 HTTPS 网页的完整路径和正文。Cloudflare:DNS 加密说明

是否构成泄漏,还取决于预期策略。例如,明确安排公司内网域名由内部 DNS 解析,是正常的分流设计;要求经过代理的查询意外发送给运营商,才是需要处理的问题。

02 接管、加密和出口分别负责什么

完整的 DNS 策略需要同时考虑接管、加密和出口。

配置层面需要解决的问题
DNS 接管应用发出的查询是否进入 Mihomo
查询加密Mihomo 与上游 DNS 之间是否使用 DoH 或 DoT
出口选择上游 DNS 连接通过代理还是直接连接

只填写 1.1.1.1 这样的地址,通常只是更换 DNS 服务商。使用 DoH 或 DoT 才涉及传输加密,而加密连接本身仍有直连和代理两种路径。Cloudflare:加密 DNS

因此,配置时应当明确指定解析服务和出口,并检查应用有没有绕过这套设置。

03 建立可检查的解析路径

可以先建立一条简单、明确的解析路径,再逐步增加分流。 以下示例使用 TUN 接管流量,将普通 DNS 查询交给 Mihomo,并让本机需要发出的上游查询经过指定代理组。

代理节点自身的域名使用独立解析服务处理。这样,在代理尚未建立时,客户端就能取得节点地址,避免解析过程反过来依赖尚未连通的代理。

图 2 · 查询与引导解析分开处理
应用查询系统 DNS / TUN
Mihomo DNS需要真实地址时
代理组必须选中代理
加密 DNS处理本机上游查询
独立引导:节点域名 → 引导 DNS(直连)→ 节点 IP → 建立代理
图示为本机上游查询路径;部分连接会将域名交由远端节点解析。

如果还不清楚 TUN 与系统代理分别接管什么,可以先看系统代理与 TUN 的区别,再调整下面的配置。

实际操作前,先备份当前配置。下面只包含 TUN 与 DNS 部分,需要通过客户端提供的配置编辑或覆写功能整合到现有配置中。

这是合并片段,不是完整配置

先备份,确认内核支持字段及代理组名称,再使用客户端的覆写或合并功能。不要覆盖节点和分流规则。

tun:
  enable: true
  auto-route: true
  auto-detect-interface: true

  # 需要支持该字段的近期 Mihomo 内核
  dns-mode: native

  dns-hijack:
    - any:53
    - tcp://any:53

  strict-route: true

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip

  # 解析 DNS 服务自身的域名
  default-nameserver:
    - tls://223.5.5.5

  # 独立解析代理节点域名
  proxy-server-nameserver:
    - "tls://223.5.5.5#DIRECT"

  # 替换为配置中真实存在的代理组名称
  nameserver:
    - "https://cloudflare-dns.com/dns-query#节点选择"

示例中的 #节点选择 指定上游 DNS 连接使用该代理组。应用前,需要将它替换成实际名称,并确认该组最终选中代理节点,也不会在失败时回退到 DIRECT。Mihomo 支持在 DNS 地址后指定代理或接口;通过代理查询时,应同时配置独立的节点域名解析服务。Mihomo DNS 配置

这里选用阿里 DNS 的 DoT 地址作为引导解析示例,该地址也出现在 Mihomo 的官方配置中。它是否适合当前网络,仍需实际验证。Mihomo 配置示例

引导解析直接连接指定服务,意味着该服务可以看到节点域名等引导查询。这是一项明确的信任选择,应当与网站域名的解析路径分别理解。

dns-mode: native 用于将系统 DNS 指向 TUN;dns-hijack 则将匹配的 DNS 连接导入内置解析模块。系统 DNS 仍指向局域网路由器时,单靠劫持配置存在平台限制。如果内核不支持 dns-mode,应先核对客户端对应的系统 DNS 接管功能。Mihomo TUN 配置

04 检查最终生效配置

配置合并之后,还需要检查最终生效的内容。 订阅原有的 nameserver-policy、fallback 和 direct-nameserver 都可能影响解析路径。新增一个 nameserver,并不会自动清除已有策略。

初次排查时,保持路径简单更容易定位问题。公司内网、NAS 或自定义局域网域名,则应按需保留专门的解析规则;公共 DNS 通常无法解析这些内部名称。

05 检查浏览器独立 DNS

浏览器的安全 DNS 会增加一条需要检查的路径。 Chrome 等浏览器可以自行使用 DoH,此时查询可能绕过 Mihomo 的 DNS 模块,但 DoH 连接仍可能经过 TUN 和代理。

排查时,可以记录浏览器原设置,临时关闭其独立的安全 DNS,让查询先统一进入系统解析路径。确认接管正常后,再决定是否恢复独立解析,并验证对应连接的出口。

Chrome 的自动模式在安全查询失败时可能使用未加密查询;选择自定义提供商时,回退行为有所不同。因此,验证时也应记录浏览器采用了哪一种模式。Chrome 官方说明

06 分三层验证

验证应同时观察解析结果和传输路径。 DNS 检测网站适合发现异常,但无法独自覆盖整台设备的所有流量。

图 3 · 从结果检查到路径证据
检测网站观察解析服务商
生效配置核对上游和出口
物理网卡检查绕行查询
每一层都需要结合预期策略:没有异常记录 ≠ 所有场景都不会泄漏
测试应记录客户端与内核版本、网络环境以及观察范围。

可以先访问 DNSLeakTest,执行 Extended test。测试会让浏览器查询一组域名,再观察哪些 DNS 服务器参与解析。同一家服务商可能使用多个服务器,所以结果中的 IP 数量不能直接作为泄漏数量。DNSLeakTest 测试原理

阅读结果时,可以参考下面的判断方式:

检测结果如何理解
出现预期的解析服务商与策略相符,继续确认连接出口
出现未预期的本地运营商检查系统 DNS、浏览器设置及接管范围
DNS 所在国家与节点不同地理位置差异本身不足以判定泄漏
出现远端节点使用的解析服务核对是否由节点完成域名解析

这里需要特别注意 Fake-IP 模式。Mihomo 可以将目标域名交给远端代理,由远端完成解析。因此,即使本机配置了 Cloudflare,检测结果也未必只出现 Cloudflare;本机 nameserver 无法统一规定远端节点的解析服务。Mihomo 解析流程

接着检查客户端的生效配置、代理组选择和可用的连接记录。缓存、日志级别及客户端展示方式都会影响观察结果,缺少某条日志只能说明当前没有看到相应记录。

如果需要更直接的证据,可以使用 Wireshark 抓取当前联网的 Wi-Fi 或以太网接口,并输入显示过滤器:

udp.port == 53 || tcp.port == 53

随后重新运行 DNS 检测,观察是否有测试域名的查询发往路由器或其他非预期服务器。该表达式用于筛选 TCP、UDP 的 53 端口流量。Wireshark 过滤器说明

抓包位置会影响结论。在 TUN 或回环接口中看到应用向 Mihomo 提交 DNS,可能属于正常接管过程;检查查询有没有离开预期路径,应重点观察实际联网的物理接口。

同时,53 端口没有查询,也只能说明这次观察中未发现相应流量。DoH 通常使用 443,DoT 通常使用 853,还需要结合目的地址和连接路径判断。Cloudflare:加密协议与端口

07 补齐 IPv6 与故障验证

IPv6 和故障状态需要分别检查。 dns.ipv6: false 控制 Mihomo DNS 对 AAAA 查询的响应,并没有关闭整台设备的 IPv6。如果当前网络支持 IPv6,应确认这部分流量同样符合接管和出口策略。Mihomo IPv6 DNS 设置

strict-route 不是独立的断线保护开关。它的作用也与平台相关。例如,Windows 下会通过防火墙规则处理多网卡 DNS 泄漏问题。对于客户端退出、内核崩溃、休眠恢复等情况,是否仍能阻止意外直连,需要另行验证断线保护机制。Mihomo 严格路由说明

完成配置后,建议保留一份简短记录:客户端和内核版本、测试网络、预期 DNS 路径,以及实际观察结果。更换订阅、更新客户端或切换网络后,按照同样的方法复查,才能持续确认这套策略仍然有效。

尚未安装客户端,可先阅读Windows 入门教程。

diff --git a/docs/content/tutorials/dns.md b/docs/content/tutorials/dns.md new file mode 100644 index 00000000..d2e124a4 --- /dev/null +++ b/docs/content/tutorials/dns.md @@ -0,0 +1,143 @@ +使用 Clash 时,代理连接正常、出口 IP 符合预期,只能说明部分网络请求已经经过代理。DNS 查询是否沿着预期路径发送,还需要单独确认。 + +这也是 DNS 防泄漏配置的重点:明确哪些查询由客户端处理,哪些交给远端节点解析,以及查询经过什么连接抵达解析服务。 + +本文面向采用 **Mihomo 内核的桌面客户端**,从解析路径出发,介绍一套可检查、可验证的配置方法。使用配置示例前,先确认客户端所用内核支持相应字段。 + + + +

01 识别两条不同的路径

+ +DNS 泄漏通常发生在流量路径分离的地方。 应用访问网站前,可能先通过系统 DNS 查询域名。如果网页连接进入代理,而查询仍发送给本地路由器或运营商,两类请求就走了不同的路径。 + +
图 1 · 网页走代理,查询可能走另一条路
应用发起请求
Mihomo接管网页连接
代理节点连接目标网站
另一路:应用 → 系统 DNS → 路由器 / 运营商
如果 DNS 查询没有按预期接管,网页出口正常仍可能伴随解析绕行。
+ +普通 DNS 查询通常以明文传输,沿途网络可以观察其中的域名。这类查询主要暴露“访问了哪个域名”,通常不包含 HTTPS 网页的完整路径和正文。[Cloudflare:DNS 加密说明](https://developers.cloudflare.com/1.1.1.1/encryption/) + +是否构成泄漏,还取决于预期策略。例如,明确安排公司内网域名由内部 DNS 解析,是正常的分流设计;要求经过代理的查询意外发送给运营商,才是需要处理的问题。 + +

02 接管、加密和出口分别负责什么

+ +完整的 DNS 策略需要同时考虑接管、加密和出口。 + +| 配置层面 | 需要解决的问题 | +|---|---| +| DNS 接管 | 应用发出的查询是否进入 Mihomo | +| 查询加密 | Mihomo 与上游 DNS 之间是否使用 DoH 或 DoT | +| 出口选择 | 上游 DNS 连接通过代理还是直接连接 | + +只填写 `1.1.1.1` 这样的地址,通常只是更换 DNS 服务商。使用 DoH 或 DoT 才涉及传输加密,而加密连接本身仍有直连和代理两种路径。[Cloudflare:加密 DNS](https://developers.cloudflare.com/1.1.1.1/encryption/) + +因此,配置时应当明确指定解析服务和出口,并检查应用有没有绕过这套设置。 + +

03 建立可检查的解析路径

+ +可以先建立一条简单、明确的解析路径,再逐步增加分流。 以下示例使用 TUN 接管流量,将普通 DNS 查询交给 Mihomo,并让本机需要发出的上游查询经过指定代理组。 + +代理节点自身的域名使用独立解析服务处理。这样,在代理尚未建立时,客户端就能取得节点地址,避免解析过程反过来依赖尚未连通的代理。 + +
图 2 · 查询与引导解析分开处理
应用查询系统 DNS / TUN
Mihomo DNS需要真实地址时
代理组必须选中代理
加密 DNS处理本机上游查询
独立引导:节点域名 → 引导 DNS(直连)→ 节点 IP → 建立代理
图示为本机上游查询路径;部分连接会将域名交由远端节点解析。
+ +如果还不清楚 TUN 与系统代理分别接管什么,可以先看[系统代理与 TUN 的区别](/a/system-proxy-vs-tun.html#tun),再调整下面的配置。 + +实际操作前,先备份当前配置。下面只包含 TUN 与 DNS 部分,需要通过客户端提供的配置编辑或覆写功能整合到现有配置中。 + +
这是合并片段,不是完整配置

先备份,确认内核支持字段及代理组名称,再使用客户端的覆写或合并功能。不要覆盖节点和分流规则。

+ +```yaml +tun: + enable: true + auto-route: true + auto-detect-interface: true + + # 需要支持该字段的近期 Mihomo 内核 + dns-mode: native + + dns-hijack: + - any:53 + - tcp://any:53 + + strict-route: true + +dns: + enable: true + listen: 127.0.0.1:1053 + enhanced-mode: fake-ip + + # 解析 DNS 服务自身的域名 + default-nameserver: + - tls://223.5.5.5 + + # 独立解析代理节点域名 + proxy-server-nameserver: + - "tls://223.5.5.5#DIRECT" + + # 替换为配置中真实存在的代理组名称 + nameserver: + - "https://cloudflare-dns.com/dns-query#节点选择" +``` + +示例中的 `#节点选择` 指定上游 DNS 连接使用该代理组。应用前,需要将它替换成实际名称,并确认该组最终选中代理节点,也不会在失败时回退到 `DIRECT`。Mihomo 支持在 DNS 地址后指定代理或接口;通过代理查询时,应同时配置独立的节点域名解析服务。[Mihomo DNS 配置](https://wiki.metacubex.one/config/dns/) + +这里选用阿里 DNS 的 DoT 地址作为引导解析示例,该地址也出现在 Mihomo 的官方配置中。它是否适合当前网络,仍需实际验证。[Mihomo 配置示例](https://wiki.metacubex.one/example/conf/) + +引导解析直接连接指定服务,意味着该服务可以看到节点域名等引导查询。这是一项明确的信任选择,应当与网站域名的解析路径分别理解。 + +`dns-mode: native` 用于将系统 DNS 指向 TUN;`dns-hijack` 则将匹配的 DNS 连接导入内置解析模块。系统 DNS 仍指向局域网路由器时,单靠劫持配置存在平台限制。如果内核不支持 `dns-mode`,应先核对客户端对应的系统 DNS 接管功能。[Mihomo TUN 配置](https://wiki.metacubex.one/config/inbound/tun/) + +

04 检查最终生效配置

+ +配置合并之后,还需要检查最终生效的内容。 订阅原有的 `nameserver-policy`、`fallback` 和 `direct-nameserver` 都可能影响解析路径。新增一个 `nameserver`,并不会自动清除已有策略。 + +初次排查时,保持路径简单更容易定位问题。公司内网、NAS 或自定义局域网域名,则应按需保留专门的解析规则;公共 DNS 通常无法解析这些内部名称。 + +

05 检查浏览器独立 DNS

+ +浏览器的安全 DNS 会增加一条需要检查的路径。 Chrome 等浏览器可以自行使用 DoH,此时查询可能绕过 Mihomo 的 DNS 模块,但 DoH 连接仍可能经过 TUN 和代理。 + +排查时,可以记录浏览器原设置,临时关闭其独立的安全 DNS,让查询先统一进入系统解析路径。确认接管正常后,再决定是否恢复独立解析,并验证对应连接的出口。 + +Chrome 的自动模式在安全查询失败时可能使用未加密查询;选择自定义提供商时,回退行为有所不同。因此,验证时也应记录浏览器采用了哪一种模式。[Chrome 官方说明](https://support.google.com/chrome/answer/10468685?hl=en&co=GENIE.Platform%3DDesktop) + +

06 分三层验证

+ +验证应同时观察解析结果和传输路径。 DNS 检测网站适合发现异常,但无法独自覆盖整台设备的所有流量。 + +
图 3 · 从结果检查到路径证据
检测网站观察解析服务商
生效配置核对上游和出口
物理网卡检查绕行查询
每一层都需要结合预期策略:没有异常记录 ≠ 所有场景都不会泄漏
测试应记录客户端与内核版本、网络环境以及观察范围。
+ +可以先访问 [DNSLeakTest](https://www.dnsleaktest.com/),执行 Extended test。测试会让浏览器查询一组域名,再观察哪些 DNS 服务器参与解析。同一家服务商可能使用多个服务器,所以结果中的 IP 数量不能直接作为泄漏数量。[DNSLeakTest 测试原理](https://www.dnsleaktest.com/what-is-the-difference.html) + +阅读结果时,可以参考下面的判断方式: + +| 检测结果 | 如何理解 | +|---|---| +| 出现预期的解析服务商 | 与策略相符,继续确认连接出口 | +| 出现未预期的本地运营商 | 检查系统 DNS、浏览器设置及接管范围 | +| DNS 所在国家与节点不同 | 地理位置差异本身不足以判定泄漏 | +| 出现远端节点使用的解析服务 | 核对是否由节点完成域名解析 | + +这里需要特别注意 Fake-IP 模式。Mihomo 可以将目标域名交给远端代理,由远端完成解析。因此,即使本机配置了 Cloudflare,检测结果也未必只出现 Cloudflare;本机 `nameserver` 无法统一规定远端节点的解析服务。[Mihomo 解析流程](https://wiki.metacubex.one/config/dns/diagram/) + +接着检查客户端的生效配置、代理组选择和可用的连接记录。缓存、日志级别及客户端展示方式都会影响观察结果,缺少某条日志只能说明当前没有看到相应记录。 + +如果需要更直接的证据,可以使用 Wireshark 抓取当前联网的 Wi-Fi 或以太网接口,并输入显示过滤器: + +```text +udp.port == 53 || tcp.port == 53 +``` + +随后重新运行 DNS 检测,观察是否有测试域名的查询发往路由器或其他非预期服务器。该表达式用于筛选 TCP、UDP 的 53 端口流量。[Wireshark 过滤器说明](https://sharkfest.wireshark.org/retrospective/sfeu/presentations24eu/03.pdf) + +抓包位置会影响结论。在 TUN 或回环接口中看到应用向 Mihomo 提交 DNS,可能属于正常接管过程;检查查询有没有离开预期路径,应重点观察实际联网的物理接口。 + +同时,53 端口没有查询,也只能说明这次观察中未发现相应流量。DoH 通常使用 443,DoT 通常使用 853,还需要结合目的地址和连接路径判断。[Cloudflare:加密协议与端口](https://developers.cloudflare.com/1.1.1.1/encryption/) + +

07 补齐 IPv6 与故障验证

+ +IPv6 和故障状态需要分别检查。 `dns.ipv6: false` 控制 Mihomo DNS 对 AAAA 查询的响应,并没有关闭整台设备的 IPv6。如果当前网络支持 IPv6,应确认这部分流量同样符合接管和出口策略。[Mihomo IPv6 DNS 设置](https://wiki.metacubex.one/config/dns/#ipv6) + +`strict-route` 不是独立的断线保护开关。它的作用也与平台相关。例如,Windows 下会通过防火墙规则处理多网卡 DNS 泄漏问题。对于客户端退出、内核崩溃、休眠恢复等情况,是否仍能阻止意外直连,需要另行验证断线保护机制。[Mihomo 严格路由说明](https://wiki.metacubex.one/config/inbound/tun/#strict-route) + +完成配置后,建议保留一份简短记录:客户端和内核版本、测试网络、预期 DNS 路径,以及实际观察结果。更换订阅、更新客户端或切换网络后,按照同样的方法复查,才能持续确认这套策略仍然有效。 + +尚未安装客户端,可先阅读[Windows 入门教程](/a/clash-verge-rev-windows.html)。 diff --git a/docs/content/tutorials/mac-client-guide.html b/docs/content/tutorials/mac-client-guide.html new file mode 100644 index 00000000..80f6b2bd --- /dev/null +++ b/docs/content/tutorials/mac-client-guide.html @@ -0,0 +1 @@ +

在 Mac 上使用免费节点,先要选对客户端和安装包,再找与它匹配的订阅格式。软件名字里有“Clash”,并不意味着所有版本的系统要求、协议支持和下载来源都相同。

这篇文章帮助你完成下载前的选择;确定使用 Clash Verge Rev 后,可以直接进入Mac 安装与连接教程。

下载前先确认三件事
系统与芯片macOS 版本、Apple 芯片或 Intel
→
官方安装包找到对应架构的 DMG
→
订阅格式使用 Clash / Mihomo 配置
图 1 · 先匹配运行环境,再导入资源,可以少走很多安装和格式排错的弯路。

01 搜索到 ClashX 时,先核对下载来源

ClashX 曾是 Mac 上常见的菜单栏代理客户端。下载时先确认项目维护者、系统要求和正式发行入口;原项目入口无法访问时,不要随意用同名下载站的安装包替代。

网上仍能看到名字相似的下载站、镜像或分支。它们需要分别核实维护者和来源,不能只凭“ClashX 官网”几个字就认定与原项目相同。已经安装旧版的用户,可以先保留自己的配置;准备新安装时,优先从能核对项目和发行记录的入口开始。

这也不等于“旧版一定不能运行”。能否打开、能否读取当前订阅、能否连接其中的节点,是三个不同的问题。某份新订阅使用了旧内核不支持的配置时,反复换下载站通常解决不了兼容性问题。

02 本站 Mac 入门以 Clash Verge Rev 为例

Clash Verge Rev 项目提供 macOS 版本,包含订阅管理、代理组选择和连接查看等功能。安装后可按Mac 使用教程完成订阅导入和连接。

它与旧版 ClashX 是不同客户端。即使都能使用某些 Clash 配置,也应按各自界面操作,不要在安装 Verge 后继续寻找 ClashX 菜单里的同名入口。

你的情况下一步
第一次在 Mac 上使用节点先核对系统要求,再安装 Clash Verge Rev
只想让浏览器访问所需网站先走规则模式与系统代理的基本流程
浏览器正常,某个应用不走代理完成基本验证后,再检查该应用代理设置或 TUN 接管
老系统无法满足当前版本要求先核对系统升级可行性;不能靠换 CPU 架构包解决系统版本限制

03 区分 Apple 芯片和 Intel 安装包

在苹果菜单中打开“关于本机”,查看 macOS 版本,以及“芯片”或“处理器”一栏。官方安装文档当前要求 macOS 12 及以上。

关于本机显示的硬件官方 DMG 的架构标记
Apple M 系列芯片aarch64
Intel 处理器x64

从官方发行页下载对应 .dmg。以 v2.5.8 为例,Source code 是源码,其他平台的 .exe、.deb、.rpm 也不是 Mac 安装包。

后续更新也可从官方发行页选择适合自己电脑的安装包。安装遇到系统确认或启动异常时,按Mac 教程的安装与排错步骤处理。

04 客户端和订阅要配套

本站免费节点页面中的分享通常会列出不同格式。使用 Clash Verge Rev 时,选择 Clash / Mihomo 订阅;它包含客户端要读取的配置内容。

v2ray、sing-box 和 Clash 配置的写法不同,文件名或链接都是一串地址,并不能说明内容可以互换。复制时同时看格式名称,避免把文章网址当成订阅链接。

三个名字,分别解决三个问题
客户端在电脑上运行和管理连接
→
订阅提供节点、代理组和规则
→
节点承担实际的远端连接
图 2 · 换客户端、更新订阅和切换节点是不同操作。节点失效时,通常先换线路或更新资源。

05 选好之后,按平台完成连接

安装包和订阅准备好后,继续阅读 Clash Verge Rev Mac 使用教程,完成导入、选择节点、系统代理和实际访问检查。

同样的订阅也可能用于其他平台,但接管流量的方法不同:Windows 用户看 Windows 入门,Linux 桌面用户看 Linux 入门。不要把 Mac 的系统设置路径照搬到其他系统。

diff --git a/docs/content/tutorials/mac-client-guide.md b/docs/content/tutorials/mac-client-guide.md new file mode 100644 index 00000000..3d0d38b8 --- /dev/null +++ b/docs/content/tutorials/mac-client-guide.md @@ -0,0 +1,57 @@ +在 Mac 上使用免费节点,先要选对客户端和安装包,再找与它匹配的订阅格式。软件名字里有“Clash”,并不意味着所有版本的系统要求、协议支持和下载来源都相同。 + +这篇文章帮助你完成下载前的选择;确定使用 Clash Verge Rev 后,可以直接进入[Mac 安装与连接教程](/a/m173.html#install)。 + +
下载前先确认三件事
系统与芯片macOS 版本、Apple 芯片或 Intel
→
官方安装包找到对应架构的 DMG
→
订阅格式使用 Clash / Mihomo 配置
图 1 · 先匹配运行环境,再导入资源,可以少走很多安装和格式排错的弯路。
+ + + +

01 搜索到 ClashX 时,先核对下载来源

+ +ClashX 曾是 Mac 上常见的菜单栏代理客户端。下载时先确认项目维护者、系统要求和正式发行入口;原项目入口无法访问时,不要随意用同名下载站的安装包替代。 + +网上仍能看到名字相似的下载站、镜像或分支。它们需要分别核实维护者和来源,不能只凭“ClashX 官网”几个字就认定与原项目相同。已经安装旧版的用户,可以先保留自己的配置;准备新安装时,优先从能核对项目和发行记录的入口开始。 + +这也不等于“旧版一定不能运行”。能否打开、能否读取当前订阅、能否连接其中的节点,是三个不同的问题。某份新订阅使用了旧内核不支持的配置时,反复换下载站通常解决不了兼容性问题。 + +

02 本站 Mac 入门以 Clash Verge Rev 为例

+ +[Clash Verge Rev 项目](https://github.com/clash-verge-rev/clash-verge-rev)提供 macOS 版本,包含订阅管理、代理组选择和连接查看等功能。安装后可按[Mac 使用教程](/a/m173.html#install)完成订阅导入和连接。 + +它与旧版 ClashX 是不同客户端。即使都能使用某些 Clash 配置,也应按各自界面操作,不要在安装 Verge 后继续寻找 ClashX 菜单里的同名入口。 + +| 你的情况 | 下一步 | +|---|---| +| 第一次在 Mac 上使用节点 | 先核对系统要求,再安装 Clash Verge Rev | +| 只想让浏览器访问所需网站 | 先走规则模式与系统代理的基本流程 | +| 浏览器正常,某个应用不走代理 | 完成基本验证后,再检查该应用代理设置或 TUN 接管 | +| 老系统无法满足当前版本要求 | 先核对系统升级可行性;不能靠换 CPU 架构包解决系统版本限制 | + +

03 区分 Apple 芯片和 Intel 安装包

+ +在苹果菜单中打开“关于本机”,查看 macOS 版本,以及“芯片”或“处理器”一栏。官方安装文档当前要求 **macOS 12 及以上**。 + +| 关于本机显示的硬件 | 官方 DMG 的架构标记 | +|---|---| +| Apple M 系列芯片 | `aarch64` | +| Intel 处理器 | `x64` | + +从[官方发行页](https://github.com/clash-verge-rev/clash-verge-rev/releases/latest)下载对应 `.dmg`。以 v2.5.8 为例,`Source code` 是源码,其他平台的 `.exe`、`.deb`、`.rpm` 也不是 Mac 安装包。 + +后续更新也可从官方发行页选择适合自己电脑的安装包。安装遇到系统确认或启动异常时,按[Mac 教程的安装与排错步骤](/a/m173.html#install)处理。 + +

04 客户端和订阅要配套

+ +本站[免费节点页面](/freenode)中的分享通常会列出不同格式。使用 Clash Verge Rev 时,选择 **Clash / Mihomo** 订阅;它包含客户端要读取的配置内容。 + +v2ray、sing-box 和 Clash 配置的写法不同,文件名或链接都是一串地址,并不能说明内容可以互换。复制时同时看格式名称,避免把文章网址当成订阅链接。 + +
三个名字,分别解决三个问题
客户端在电脑上运行和管理连接
→
订阅提供节点、代理组和规则
→
节点承担实际的远端连接
图 2 · 换客户端、更新订阅和切换节点是不同操作。节点失效时,通常先换线路或更新资源。
+ +

05 选好之后,按平台完成连接

+ +安装包和订阅准备好后,继续阅读 [Clash Verge Rev Mac 使用教程](/a/m173.html#import),完成导入、选择节点、系统代理和实际访问检查。 + +同样的订阅也可能用于其他平台,但接管流量的方法不同:Windows 用户看 [Windows 入门](/a/clash-verge-rev-windows.html),Linux 桌面用户看 [Linux 入门](/a/m174.html)。不要把 Mac 的系统设置路径照搬到其他系统。 + +
参考资料:Clash Verge Rev v2.5.8 发行页、官方安装文档。
diff --git a/docs/content/tutorials/migration.html b/docs/content/tutorials/migration.html new file mode 100644 index 00000000..bd9cddd0 --- /dev/null +++ b/docs/content/tutorials/migration.html @@ -0,0 +1 @@ +

从旧版 Clash for Windows 迁移时,最重要的是把订阅和自定义规则保留下来,再确认新客户端真正接管了需要代理的连接。本文使用 Clash Verge Rev,完成从下载安装到连接验证的整个过程。

01 先保存旧配置,再切换客户端

保留原订阅链接,以及自己添加的规则、代理组和覆写文件,方便在新客户端中重新导入。

可以先安装新客户端;准备启用它时,再关闭旧客户端的系统代理和 TUN,并退出旧程序。两个客户端同时接管网络,容易出现端口、系统代理或路由冲突。确认新客户端可用后,再决定是否卸载旧版。

旧配置并不一定需要整份搬过去。只有常规订阅时,重新导入通常更清楚;有自定义配置时,先用原订阅建立可用连接,再逐项迁移并检查。

02 从官方发行页下载安装

打开 Clash Verge Rev 官方下载页,在 Windows 安装包中选择与电脑架构相符的版本。安装包按电脑架构选择,版本以官方发行页为准。

你的电脑选择方式
常见 Intel / AMD 处理器电脑Windows x64 安装包
Windows on ARM 设备Windows ARM64 安装包
不确定架构在 Windows“设置 → 系统 → 系统信息”中查看系统类型

本文适用于 Windows 10 / 11。不要给 Windows 7 强装新版本。优先使用普通安装包;如果缺少 WebView2 导致窗口无法显示,再按官方说明安装运行环境,或选择发行页提供的内置 WebView2 版本。具体兼容要求见官方安装说明。

03 导入并启用一份订阅

  1. 在本站免费节点页面中复制适用于 Clash / Mihomo 的订阅地址;仍在使用的旧订阅也可以重新导入。不要把文章网页地址当成订阅。
  2. 打开 Clash Verge Rev 的“订阅”页面,粘贴链接并导入。
  3. 确认出现订阅卡片,并将它设为当前使用的配置。仅有卡片不代表已经启用。
  4. 进入“代理”页面,确认能看到节点或代理组。
官方导入订阅示例:在订阅页面粘贴订阅链接并点击导入
图 1 · 官方文档中的订阅导入示例。窗口样式仅作定位参考,可点击查看大图。图片来源

如果拿到的是本地 YAML 文件,可使用客户端的本地配置导入功能。远程订阅可以刷新获取更新,本地文件导入则不会自动变成远程订阅。详细方式见官方订阅管理说明。

导入时报错,先核对链接是否完整、订阅是否有效,以及返回的是否为兼容配置。出现证书错误应检查系统时间、链接域名与服务商状态,不要通过关闭证书验证来掩盖问题。

04 分别选择“如何接管”和“如何分流”

这两组设置解决不同问题。系统代理、TUN 决定流量怎样进入客户端;规则、全局、直连决定进入后的流量怎样出去。

图 2 · 两个独立的选择
应用浏览器、下载器等
→
接管方式系统代理 / TUN
→
分流模式规则 / 全局 / 直连
→
实际出口代理节点或直接连接
切换到“全局”不会自动接管所有应用;应用请求仍需先进入客户端。

第一次使用,建议先启用 系统代理 + 规则模式。在需要代理的策略组里选一个可用节点,注意不要误选 DIRECT。规则模式按当前配置决定流量去向,并不天然保证“国内全部直连、国外全部代理”。

模式适合怎样使用
规则日常使用;根据订阅中的规则选择出口
全局临时排查分流问题;进入内核的普通业务连接使用全局策略组
直连让内核直接连接目标;不等于退出客户端或恢复系统设置

如果浏览器可用、某个应用仍无法连接,先确认该应用是否遵循系统代理。确有需要时,再按客户端提示安装或启用所需服务,并开启 TUN。TUN 的接管范围仍受平台、路由与排除规则影响。相关操作见官方快速入门。

05 用一次真实请求确认连接

不要只看开关颜色或节点延迟。按下面顺序检查,更容易发现问题:

  1. 配置已生效。 当前订阅已启用,代理组最终选中的是预期节点。
  2. 请求被接管。 访问一个你明确希望走代理的网站,在客户端连接记录中找到它,并查看匹配规则和出口链路。
  3. 结果符合策略。 页面正常响应;如用 IP 查询网站辅助验证,要先确认该查询请求本身走了代理。规则模式下,某个 IP 查询网站直连并不证明其他网站也直连。

延迟测试只能说明节点对测试目标的连通情况,不能代替网页、下载或实际业务的测试。完成这些检查后,再逐项恢复自定义规则。

06 按故障出现的位置排查

现象优先检查
安装包无法运行系统版本、x64 / ARM64 架构是否匹配
只有托盘图标、主窗口打不开WebView2 是否正常,参考官方 Windows FAQ
订阅导入失败链接完整性、有效期、配置格式与错误信息
节点列表正常,网页仍打不开当前配置、策略组选择、系统代理状态与连接记录
浏览器可用,其他应用不可用应用是否遵循系统代理;是否需要 TUN
开启 TUN 后局域网或其他 VPN 异常先恢复原接管方式,再检查路由冲突和排除项
退出客户端后仍无法访问网络是否留下指向本机已停止端口的系统代理

最后一种情况,可查看 Windows“设置 → 网络和 Internet → 代理”。确认是旧客户端留下的本机手动代理后再关闭;工作单位管理的代理设置应按其管理要求处理。更多环境问题见官方 Windows 常见问题。

下一步:检查 DNS 的实际路径

客户端能够联网之后,还可以单独核对 DNS 接管、加密解析和出口。继续阅读:Clash 进阶:DNS 防泄漏配置与验证。

diff --git a/docs/content/tutorials/migration.md b/docs/content/tutorials/migration.md new file mode 100644 index 00000000..aa3542ee --- /dev/null +++ b/docs/content/tutorials/migration.md @@ -0,0 +1,78 @@ +从旧版 Clash for Windows 迁移时,最重要的是把订阅和自定义规则保留下来,再确认新客户端真正接管了需要代理的连接。本文使用 **Clash Verge Rev**,完成从下载安装到连接验证的整个过程。 + + + +

01 先保存旧配置,再切换客户端

+ +保留原订阅链接,以及自己添加的规则、代理组和覆写文件,方便在新客户端中重新导入。 + +可以先安装新客户端;准备启用它时,再关闭旧客户端的系统代理和 TUN,并退出旧程序。两个客户端同时接管网络,容易出现端口、系统代理或路由冲突。确认新客户端可用后,再决定是否卸载旧版。 + +旧配置并不一定需要整份搬过去。只有常规订阅时,重新导入通常更清楚;有自定义配置时,先用原订阅建立可用连接,再逐项迁移并检查。 + +

02 从官方发行页下载安装

+ +打开 [Clash Verge Rev 官方下载页](https://github.com/clash-verge-rev/clash-verge-rev/releases/latest),在 Windows 安装包中选择与电脑架构相符的版本。安装包按电脑架构选择,版本以官方发行页为准。 + +| 你的电脑 | 选择方式 | +|---|---| +| 常见 Intel / AMD 处理器电脑 | Windows x64 安装包 | +| Windows on ARM 设备 | Windows ARM64 安装包 | +| 不确定架构 | 在 Windows“设置 → 系统 → 系统信息”中查看系统类型 | + +本文适用于 Windows 10 / 11。不要给 Windows 7 强装新版本。优先使用普通安装包;如果缺少 WebView2 导致窗口无法显示,再按官方说明安装运行环境,或选择发行页提供的内置 WebView2 版本。具体兼容要求见[官方安装说明](https://www.clashverge.dev/install.html)。 + +

03 导入并启用一份订阅

+ +1. 在本站[免费节点页面](/freenode)中复制适用于 **Clash / Mihomo** 的订阅地址;仍在使用的旧订阅也可以重新导入。不要把文章网页地址当成订阅。 +2. 打开 Clash Verge Rev 的“订阅”页面,粘贴链接并导入。 +3. 确认出现订阅卡片,并将它设为当前使用的配置。仅有卡片不代表已经启用。 +4. 进入“代理”页面,确认能看到节点或代理组。 + +
官方导入订阅示例:在订阅页面粘贴订阅链接并点击导入
图 1 · 官方文档中的订阅导入示例。窗口样式仅作定位参考,可点击查看大图。图片来源
+ +如果拿到的是本地 YAML 文件,可使用客户端的本地配置导入功能。远程订阅可以刷新获取更新,本地文件导入则不会自动变成远程订阅。详细方式见[官方订阅管理说明](https://www.clashverge.dev/guide/profile.html)。 + +导入时报错,先核对链接是否完整、订阅是否有效,以及返回的是否为兼容配置。出现证书错误应检查系统时间、链接域名与服务商状态,不要通过关闭证书验证来掩盖问题。 + +

04 分别选择“如何接管”和“如何分流”

+ +这两组设置解决不同问题。**系统代理、TUN 决定流量怎样进入客户端;规则、全局、直连决定进入后的流量怎样出去。** + +
图 2 · 两个独立的选择
应用浏览器、下载器等
→
接管方式系统代理 / TUN
→
分流模式规则 / 全局 / 直连
→
实际出口代理节点或直接连接
切换到“全局”不会自动接管所有应用;应用请求仍需先进入客户端。
+ +第一次使用,建议先启用 **系统代理 + 规则模式**。在需要代理的策略组里选一个可用节点,注意不要误选 `DIRECT`。规则模式按当前配置决定流量去向,并不天然保证“国内全部直连、国外全部代理”。 + +| 模式 | 适合怎样使用 | +|---|---| +| 规则 | 日常使用;根据订阅中的规则选择出口 | +| 全局 | 临时排查分流问题;进入内核的普通业务连接使用全局策略组 | +| 直连 | 让内核直接连接目标;不等于退出客户端或恢复系统设置 | + +如果浏览器可用、某个应用仍无法连接,先确认该应用是否遵循系统代理。确有需要时,再按客户端提示安装或启用所需服务,并开启 TUN。TUN 的接管范围仍受平台、路由与排除规则影响。相关操作见[官方快速入门](https://www.clashverge.dev/guide/quickstart.html)。 + +

05 用一次真实请求确认连接

+ +不要只看开关颜色或节点延迟。按下面顺序检查,更容易发现问题: + +1. **配置已生效。** 当前订阅已启用,代理组最终选中的是预期节点。 +2. **请求被接管。** 访问一个你明确希望走代理的网站,在客户端连接记录中找到它,并查看匹配规则和出口链路。 +3. **结果符合策略。** 页面正常响应;如用 IP 查询网站辅助验证,要先确认该查询请求本身走了代理。规则模式下,某个 IP 查询网站直连并不证明其他网站也直连。 + +延迟测试只能说明节点对测试目标的连通情况,不能代替网页、下载或实际业务的测试。完成这些检查后,再逐项恢复自定义规则。 + +

06 按故障出现的位置排查

+ +| 现象 | 优先检查 | +|---|---| +| 安装包无法运行 | 系统版本、x64 / ARM64 架构是否匹配 | +| 只有托盘图标、主窗口打不开 | WebView2 是否正常,参考官方 Windows FAQ | +| 订阅导入失败 | 链接完整性、有效期、配置格式与错误信息 | +| 节点列表正常,网页仍打不开 | 当前配置、策略组选择、系统代理状态与连接记录 | +| 浏览器可用,其他应用不可用 | 应用是否遵循系统代理;是否需要 TUN | +| 开启 TUN 后局域网或其他 VPN 异常 | 先恢复原接管方式,再检查路由冲突和排除项 | +| 退出客户端后仍无法访问网络 | 是否留下指向本机已停止端口的系统代理 | + +最后一种情况,可查看 Windows“设置 → 网络和 Internet → 代理”。确认是旧客户端留下的本机手动代理后再关闭;工作单位管理的代理设置应按其管理要求处理。更多环境问题见[官方 Windows 常见问题](https://www.clashverge.dev/faq/windows.html)。 + +
下一步:检查 DNS 的实际路径

客户端能够联网之后,还可以单独核对 DNS 接管、加密解析和出口。继续阅读:Clash 进阶:DNS 防泄漏配置与验证。

diff --git a/docs/content/tutorials/quantumult-x-ios.html b/docs/content/tutorials/quantumult-x-ios.html new file mode 100644 index 00000000..8ee072bf --- /dev/null +++ b/docs/content/tutorials/quantumult-x-ios.html @@ -0,0 +1 @@ +

Quantumult X 可以在 iPhone、iPad 上管理代理节点、选择策略并接管连接。第一次使用时,关键是把订阅变成客户端能读取的节点,再确认流量确实使用了选中的线路。

本文只讲 Quantumult X。Quantumult 是另一个应用,两者的界面和配置不能混用。这里也不涉及重写脚本、广告过滤或 HTTPS 解密,先完成基本连接即可。

从免费订阅到第一次连接
安装 Quantumult X核对开发者与系统要求
→
导入节点资源必要时使用资源解析器
→
选择节点与策略确认请求的去向
→
开启连接允许VPN配置并实际访问
图 1 · 订阅导入、策略选择和VPN开关分别对应不同环节,缺少其中一步都可能无法使用。

01 从 App Store 获取 Quantumult X

打开Quantumult X 的 App Store 页面,核对应用名和开发者 Cross Utility Ltd。这是付费应用,实际价格与是否可购买,以你使用的商店地区为准。

以 1.8.1 为例,系统要求为 iOS 15.0 / iPadOS 15.0 或更高版本。若当前商店搜索不到,不要把名字相近的应用当成同一个客户端;先核对商店是否提供该应用。

安装后先打开应用查看初始界面。不同版本的“节点资源”“策略”和连接开关位置可能略有变化,可按功能名称查找。

02 先看订阅是什么格式

在本站免费节点页面中打开较新的分享。页面会提供不同格式的资源,但目前不能把本站通用订阅直接视为 Quantumult X 原生订阅。

手里的内容如何处理
明确标注为Quantumult X节点资源可按原生节点资源导入
本站v2ray订阅需要能识别其内容的资源解析器,再导入节点
Clash / Mihomo或sing-box完整配置不要当成Quantumult X完整配置直接覆盖
普通文章网址先进入文章,复制里面真正的订阅地址

“资源解析”主要解决格式转换,不会让失效节点恢复,也不能保证任意协议和参数都能转换。第一批导入失败时,先确认格式与解析器,不必立刻重装应用。

03 通用订阅需要先配置资源解析器

通用订阅可通过 KOP-XIAO 资源解析器转换为 Quantumult X 能读取的节点资源。它是第三方脚本,并非 Quantumult X 内置功能。可以先在作者仓库查看说明和脚本内容,再决定使用。

在应用设置中找到当前配置的编辑入口。在已有的 [general] 区域内加入或修改这一项,保存配置:

[general]
resource_parser_url = https://raw.githubusercontent.com/KOP-XIAO/QuantumultX/master/Scripts/resource-parser.js

这里展示了节名,方便定位;已有 [general] 时,只放入其中的 resource_parser_url 这一行,不要重复建立整段,也不要把当前配置全部替换成这两行。若原来已经指定了其他解析器,先保留原配置副本,再决定是否更换。

解析器由客户端下载并在本地解析资源内容。这个路径仍需要设备能够访问;下载失败时先核对脚本地址和连接条件,不能把“已填入地址”当成“脚本已加载成功”。使用上面给出的解析器地址,避免误填其他示例脚本。

资源解析器做了什么
下载订阅内容取得分享链接或节点列表
→
客户端运行解析器转换支持的格式与参数
→
生成可用节点条目随后再测试连接
图 2 · 转换成功只表示客户端能读取节点。协议兼容性、节点是否在线和实际访问仍需分别检查。

04 添加节点资源,并确认列表出现

复制本站较新分享中的 v2ray 订阅地址,进入 Quantumult X 设置中的节点资源或节点引用管理,添加远程资源:

  1. 为资源填写一个容易辨认的名称,例如“本站免费节点”。
  2. 粘贴实际订阅地址,启用该资源。
  3. 对需要转换的通用订阅开启资源解析选项,再保存并更新。
  4. 返回节点列表,确认出现了实际节点,而不是只有资源名称或错误提示。

如果当前版本界面入口不易辨认,也可以按开发者配置格式,在已有的 [server_remote] 区域加入资源行:

[server_remote]
https://example.invalid/subscription, tag=本站免费节点, opt-parser=true, enabled=true

上面的地址是占位示例,必须换成从本站复制的真实订阅链接。 已有节名时只加入资源行,保留原来的其他配置;不要同时在界面和配置中重复添加同一份资源。opt-parser=true 表示对这份资源调用解析器,enabled=true 表示启用资源。

原生 Quantumult X 节点资源通常不需要这个转换步骤。导入结果少于原订阅节点数时,可能存在解析器或客户端不支持的参数,应检查资源更新提示,不把条目数量当成连接质量。

05 选择策略,再开启 VPN 连接

有了节点后,先选一条线路作为当前代理使用的节点。Quantumult X 的策略组负责选择节点,分流规则负责选择策略;具体名称取决于当前配置,导入一份节点资源不会自动生成你想要的全部分流规则。

首次排查可以暂时使用应用的全局代理模式,并确认其当前策略选中了实际节点,而不是 direct / 直连;先减少规则差异,确认这一条线路能够工作。完成验证后再切回规则分流,检查常用服务是否按预期选择策略。全局代理模式也不等于已经完成所有泄漏检查。

开启应用连接开关。首次连接时,iOS 会询问是否允许添加 VPN 配置,按系统提示允许并完成设备验证。基础代理使用不需要安装用于 HTTPS 解密的根证书。

连接后打开 Safari,访问实际需要的网页;再查看应用中的请求记录,确认目标域名、命中策略和节点。看到系统VPN标记只说明VPN配置在运行,并不能单独证明节点可达或目标服务可用。

06 日常更新与停止使用

要做的事建议操作
当前节点不通在当前策略中换其他节点,再重新请求
订阅节点需要刷新在节点资源管理中更新对应资源
旧批次普遍失效回本站免费节点页面查看较新的分享,按需要更新资源地址
停止代理关闭应用连接开关,并确认VPN已断开
启动后又自动连接检查是否启用了按需连接及其他相关自动化设置

如果同时使用 Mac,可以继续看Mac 客户端下载指南。Mac 上的 Clash Verge Rev 需要对应的 Clash / Mihomo 订阅,不能把这篇教程的 Quantumult X 配置直接搬过去。

07 常见问题

订阅更新成功,为什么没有节点? 核对导入的是节点资源而非文章页;对通用订阅,检查解析器是否成功下载,以及该资源是否开启解析。再看资源是否启用、内容是否为空或包含不支持的格式。

节点有延迟,网页还是打不开。 延迟检查只是一次特定请求;目标网站、出口策略或当前线路仍可能失败。查看实际请求记录,再尝试其他节点或另一个目标,分开判断节点和网站的问题。

VPN已连接,但走的是直连。 检查运行模式、命中规则与策略组选择。只更新订阅不会自动把现有的直连策略改为某个节点。

别的教程让我导入完整配置。 完整配置可能同时改变节点资源、规则、DNS、脚本和重写设置。本文只需要完成节点连接,导入前先看清它会覆盖哪些部分,保留自己的原配置。

diff --git a/docs/content/tutorials/quantumult-x-ios.md b/docs/content/tutorials/quantumult-x-ios.md new file mode 100644 index 00000000..3de5ec96 --- /dev/null +++ b/docs/content/tutorials/quantumult-x-ios.md @@ -0,0 +1,99 @@ +Quantumult X 可以在 iPhone、iPad 上管理代理节点、选择策略并接管连接。第一次使用时,关键是把订阅变成客户端能读取的节点,再确认流量确实使用了选中的线路。 + +本文只讲 **Quantumult X**。Quantumult 是另一个应用,两者的界面和配置不能混用。这里也不涉及重写脚本、广告过滤或 HTTPS 解密,先完成基本连接即可。 + +
从免费订阅到第一次连接
安装 Quantumult X核对开发者与系统要求
→
导入节点资源必要时使用资源解析器
→
选择节点与策略确认请求的去向
→
开启连接允许VPN配置并实际访问
图 1 · 订阅导入、策略选择和VPN开关分别对应不同环节,缺少其中一步都可能无法使用。
+ + + +

01 从 App Store 获取 Quantumult X

+ +打开[Quantumult X 的 App Store 页面](https://apps.apple.com/us/app/quantumult-x/id1443988620),核对应用名和开发者 **Cross Utility Ltd**。这是付费应用,实际价格与是否可购买,以你使用的商店地区为准。 + +以 **1.8.1** 为例,系统要求为 **iOS 15.0 / iPadOS 15.0 或更高版本**。若当前商店搜索不到,不要把名字相近的应用当成同一个客户端;先核对商店是否提供该应用。 + +安装后先打开应用查看初始界面。不同版本的“节点资源”“策略”和连接开关位置可能略有变化,可按功能名称查找。 + +

02 先看订阅是什么格式

+ +在本站[免费节点页面](/freenode)中打开较新的分享。页面会提供不同格式的资源,但**目前不能把本站通用订阅直接视为 Quantumult X 原生订阅**。 + +| 手里的内容 | 如何处理 | +|---|---| +| 明确标注为Quantumult X节点资源 | 可按原生节点资源导入 | +| 本站v2ray订阅 | 需要能识别其内容的资源解析器,再导入节点 | +| Clash / Mihomo或sing-box完整配置 | 不要当成Quantumult X完整配置直接覆盖 | +| 普通文章网址 | 先进入文章,复制里面真正的订阅地址 | + +“资源解析”主要解决格式转换,不会让失效节点恢复,也不能保证任意协议和参数都能转换。第一批导入失败时,先确认格式与解析器,不必立刻重装应用。 + +

03 通用订阅需要先配置资源解析器

+ +通用订阅可通过 [KOP-XIAO 资源解析器](https://github.com/KOP-XIAO/QuantumultX)转换为 Quantumult X 能读取的节点资源。它是**第三方脚本**,并非 Quantumult X 内置功能。可以先在作者仓库查看说明和脚本内容,再决定使用。 + +在应用设置中找到当前配置的编辑入口。在已有的 `[general]` 区域内加入或修改这一项,保存配置: + +```ini +[general] +resource_parser_url = https://raw.githubusercontent.com/KOP-XIAO/QuantumultX/master/Scripts/resource-parser.js +``` + +这里展示了节名,方便定位;已有 `[general]` 时,只放入其中的 `resource_parser_url` 这一行,不要重复建立整段,也不要把当前配置全部替换成这两行。若原来已经指定了其他解析器,先保留原配置副本,再决定是否更换。 + +解析器由客户端下载并在本地解析资源内容。这个路径仍需要设备能够访问;下载失败时先核对脚本地址和连接条件,不能把“已填入地址”当成“脚本已加载成功”。使用上面给出的解析器地址,避免误填其他示例脚本。 + +
资源解析器做了什么
下载订阅内容取得分享链接或节点列表
→
客户端运行解析器转换支持的格式与参数
→
生成可用节点条目随后再测试连接
图 2 · 转换成功只表示客户端能读取节点。协议兼容性、节点是否在线和实际访问仍需分别检查。
+ +

04 添加节点资源,并确认列表出现

+ +复制本站较新分享中的 **v2ray 订阅地址**,进入 Quantumult X 设置中的节点资源或节点引用管理,添加远程资源: + +1. 为资源填写一个容易辨认的名称,例如“本站免费节点”。 +2. 粘贴实际订阅地址,启用该资源。 +3. 对需要转换的通用订阅开启资源解析选项,再保存并更新。 +4. 返回节点列表,确认出现了实际节点,而不是只有资源名称或错误提示。 + +如果当前版本界面入口不易辨认,也可以按开发者配置格式,在已有的 `[server_remote]` 区域加入资源行: + +```ini +[server_remote] +https://example.invalid/subscription, tag=本站免费节点, opt-parser=true, enabled=true +``` + +**上面的地址是占位示例,必须换成从本站复制的真实订阅链接。** 已有节名时只加入资源行,保留原来的其他配置;不要同时在界面和配置中重复添加同一份资源。`opt-parser=true` 表示对这份资源调用解析器,`enabled=true` 表示启用资源。 + +原生 Quantumult X 节点资源通常不需要这个转换步骤。导入结果少于原订阅节点数时,可能存在解析器或客户端不支持的参数,应检查资源更新提示,不把条目数量当成连接质量。 + +

05 选择策略,再开启 VPN 连接

+ +有了节点后,先选一条线路作为当前代理使用的节点。Quantumult X 的策略组负责选择节点,分流规则负责选择策略;具体名称取决于当前配置,导入一份节点资源不会自动生成你想要的全部分流规则。 + +首次排查可以暂时使用应用的**全局代理模式**,并确认其当前策略选中了实际节点,而不是 `direct` / 直连;先减少规则差异,确认这一条线路能够工作。完成验证后再切回规则分流,检查常用服务是否按预期选择策略。全局代理模式也不等于已经完成所有泄漏检查。 + +开启应用连接开关。首次连接时,iOS 会询问是否允许添加 VPN 配置,按系统提示允许并完成设备验证。基础代理使用不需要安装用于 HTTPS 解密的根证书。 + +连接后打开 Safari,访问实际需要的网页;再查看应用中的请求记录,确认目标域名、命中策略和节点。看到系统VPN标记只说明VPN配置在运行,并不能单独证明节点可达或目标服务可用。 + +

06 日常更新与停止使用

+ +| 要做的事 | 建议操作 | +|---|---| +| 当前节点不通 | 在当前策略中换其他节点,再重新请求 | +| 订阅节点需要刷新 | 在节点资源管理中更新对应资源 | +| 旧批次普遍失效 | 回本站免费节点页面查看较新的分享,按需要更新资源地址 | +| 停止代理 | 关闭应用连接开关,并确认VPN已断开 | +| 启动后又自动连接 | 检查是否启用了按需连接及其他相关自动化设置 | + +如果同时使用 Mac,可以继续看[Mac 客户端下载指南](/a/m172.html#download)。Mac 上的 Clash Verge Rev 需要对应的 Clash / Mihomo 订阅,不能把这篇教程的 Quantumult X 配置直接搬过去。 + +

07 常见问题

+ +**订阅更新成功,为什么没有节点?** 核对导入的是节点资源而非文章页;对通用订阅,检查解析器是否成功下载,以及该资源是否开启解析。再看资源是否启用、内容是否为空或包含不支持的格式。 + +**节点有延迟,网页还是打不开。** 延迟检查只是一次特定请求;目标网站、出口策略或当前线路仍可能失败。查看实际请求记录,再尝试其他节点或另一个目标,分开判断节点和网站的问题。 + +**VPN已连接,但走的是直连。** 检查运行模式、命中规则与策略组选择。只更新订阅不会自动把现有的直连策略改为某个节点。 + +**别的教程让我导入完整配置。** 完整配置可能同时改变节点资源、规则、DNS、脚本和重写设置。本文只需要完成节点连接,导入前先看清它会覆盖哪些部分,保留自己的原配置。 + +
参考资料:开发者示例配置、解析器作者源码。
diff --git a/docs/content/tutorials/system-proxy-tun.html b/docs/content/tutorials/system-proxy-tun.html new file mode 100644 index 00000000..fab97049 --- /dev/null +++ b/docs/content/tutorials/system-proxy-tun.html @@ -0,0 +1 @@ +

浏览器能打开网页,终端却一直超时;已经切到“全局”,游戏还是连不上;打开 TUN 后能用了,又担心所有网站都被送到国外。遇到这些情况,先分清两件事:流量有没有进入代理客户端,以及进入以后走哪个出口。

系统代理和 TUN 主要解决第一件事,规则、全局和直连模式主要解决第二件事。本文以 Clash Verge Rev 和 Mihomo 桌面客户端为例,说明它们的区别、适用场景和检查方法。

01 系统代理:让应用按设置转交请求

打开 Clash Verge Rev 的“系统代理”,客户端会修改操作系统的代理设置,把代理地址指向本机正在监听的端口。愿意读取并遵循这项设置的应用,就会把相应请求交给客户端处理。浏览器通常可以通过这种方式使用代理。官方快速入门

这里的关键是“应用遵循设置”。有的软件读取系统设置,有的软件使用自己的代理配置,还有的软件直接建立连接。同一台电脑上,浏览器正常、另一个应用不走代理,并不矛盾。

图 1 · 系统代理依赖应用配合
应用读取设置使用系统指定的代理
本机代理端口请求进入 Mihomo
匹配出口直连或代理节点
不遵循系统代理的应用:仍按自己的网络设置连接,不会仅因这个开关而进入 Mihomo。
这也解释了为什么“浏览器能用”不能代表电脑上每个应用都已经走代理。

如果应用提供 HTTP 或 SOCKS 代理选项,可以单独指向客户端的本机端口。地址通常是 127.0.0.1,端口应查看客户端当前设置,不要照抄别人的数字;HTTP、SOCKS 和混合端口也要对应正确。

终端工具同样需要看各自支持什么。以 Linux 上的 curl 为例,可以先用单条命令指定代理的方法检查,不必为了一个工具马上接管整台电脑。

02 TUN:通过虚拟网卡接收流量

TUN 会创建虚拟网络接口,并通过路由把符合接管条件的 IP 流量交给内核。应用不必先学会使用 HTTP 或 SOCKS 代理,因此它常用于系统代理无法覆盖的程序。Mihomo 可以处理通过 TUN 进入的 TCP、UDP 流量,但最终能否完成连接,还取决于配置、节点和目标服务。官方名词解释

图 2 · TUN 在网络路由这一层接管
应用发起连接无需读取系统代理
系统路由 → TUN进入虚拟网卡
Mihomo 处理再决定实际出口
被排除的地址、接口或其他未进入 TUN 的连接,仍可能走原来的网络路径。
TUN 扩大了接管范围,但开关亮着不等于每一条连接都已被接管。

TUN 也有接管范围。自动路由、排除网段、IPv6 设置及其他 VPN 的路由,都可能影响实际路径。例如,把某个局域网网段排除在 TUN 之外,就是让它绕过这层接管;这与连接进入 Mihomo 后命中 DIRECT 规则不同。Mihomo TUN 配置、代理绕过说明

日常使用图形客户端时,优先使用它提供的 TUN 设置。建立网卡和修改路由需要相应权限;Clash Verge Rev 的服务模式可让具有权限的后台服务启动内核,不代表必须一直以管理员身份运行整个界面。服务模式说明

03 “全局”和 TUN 不是同一个维度

把“规则”改成“全局”,改变的是进入内核后的出口选择。一个完全没有进入客户端的应用,不会因为切到全局就自动被接管。

反过来,开启 TUN 也不要求使用全局模式。TUN + 规则模式可以接管更多应用,同时继续按规则让部分连接直连、部分连接使用节点。规则与全局模式说明

图 3 · 先进入客户端,再决定去哪里
第一步:接管系统代理 / 应用代理 / TUN
第二步:选择出口规则 / 全局 / 直连
第三步:建立连接本地网络或所选节点
排错也按这个顺序进行:先找有没有进入,再看实际出口,最后判断线路是否可用。
常见组合实际含义
系统代理 + 规则遵循系统代理的请求进入客户端,再按当前配置分流
系统代理 + 全局进入内核的普通业务连接使用全局策略;未被接管的应用仍可能绕过
TUN + 规则被 TUN 接管的连接按规则选择出口,并非全部使用代理节点
TUN + 全局被接管的普通业务连接使用全局策略;仍需查看所选策略是否为可用节点

一个具体例子:浏览器和下载工具访问同一域名,浏览器连接记录里显示了节点,下载工具却没有记录。此时应优先检查下载工具的代理设置或接管方式;反复切换全局,通常没有解决前面的缺口。

04 按应用需求选择,不必一开始全部打开

你要完成的事可以先这样做
主要浏览网页,常用软件已经正常使用系统代理 + 规则模式
只有一个应用不跟随系统设置,且自带代理选项给该应用配置正确的本机代理端口
多个应用不支持代理设置,希望统一处理考虑 TUN + 规则模式,再逐个检查所需应用
游戏或语音涉及 UDP检查 TUN 接管,同时确认所选节点支持所需 UDP 转发
需要同时访问公司 VPN、NAS 或局域网设备先明确这些连接的路径,再设置绕过或直连,避免盲目全局接管

TUN 不是加速档位。 游戏登录网页能打开,不代表游戏数据传输已经正常;节点对网页可用,也不代表它能承载所需的 UDP。选择方式要看应用连接是否按预期工作,而不是哪个开关听起来更强。

系统代理和 TUN 可以同时存在,但两个开关都开不代表效果翻倍。应用主动交给本机端口的请求,本来就已进入客户端;其他连接可能由 TUN 接管。排错时,先明确正在验证哪条路径,比同时改动多个设置更容易找到原因。

05 从系统代理切到 TUN,怎样确认有效

先确保客户端已经导入配置、选中可用节点,并完成基本连接。尚未完成这一步,可以按对应平台的教程操作:Windows、Mac、Linux。

  1. 记录原来的设置。 包括系统代理、TUN 开关和当前代理组。保持订阅、节点和规则模式不变,便于对比。
  2. 按客户端提示启用服务和 TUN。 若开关自动关闭或提示权限错误,先处理服务状态与具体错误,不要继续叠加 DNS、协议栈等改动。
  3. 排除其他入口的干扰。 若要确认某个应用是否由 TUN 接管,暂时关闭本客户端的系统代理,并检查该应用是否另设了代理;有的话记录原值,再临时停用。只关闭系统代理,不能排除应用自己的代理设置。
  4. 让目标应用发起新连接。 重连应用或重新打开目标内容,避免只观察缓存页面和原有长连接。
  5. 查看连接记录。 按域名、目标 IP 或可用的进程信息定位请求,查看匹配规则、出口策略,以及界面或日志提供的入站信息。应走节点的请求如果显示 DIRECT,需要回到分流规则检查。
  6. 检查日常需要的本地服务。 包括局域网设备、公司内网等;确认没有因路由变化失去访问能力,再保留这套设置。

关掉系统代理后应用仍能联网,只能说明它不依赖刚才关闭的那项设置。还要结合新连接记录和实际出口,才能判断 TUN 是否按预期接管;应用本来就能直连时,单凭“能打开”尤其容易误判。

如果切换后异常,先关闭 TUN,恢复刚才记录的系统代理和应用设置,让连接回到原先可用的状态,再按下一节定位。

06 按现象定位,少做无关改动

浏览器能用,终端或另一个应用不能用

先检查该应用是否跟随系统代理,或者是否需要独立配置。观察它发起新请求时,客户端有没有相应连接记录。记录里没有出现时,先清除列表筛选、重试并查看日志,排查接管问题;已经出现时,再看命中的规则和实际出口。

开了 TUN,流量仍显示 DIRECT

DIRECT 表示这条连接由客户端直连,并不等于 TUN 没有工作。检查它是否命中了局域网、国内地址等直连规则,或代理组本身选中了 DIRECT。需要改变的是对应出口策略,而不是反复重启虚拟网卡。

网页正常,游戏或语音仍然失败

把登录请求和实时数据连接分开看。后者可能使用不同的地址、端口和 UDP。确认目标连接已进入客户端,再检查节点是否支持相关转发;网页测试成功不能代替这项检查。

一开 TUN,局域网、公司 VPN 或整个网络就异常

先恢复原先可用的方式,再检查路由重叠、网段冲突和客户端日志。系统代理绕过、TUN 路由排除与内核 DIRECT 规则各自发生在不同位置,不应混为一谈。不要把删除网卡或关闭全部防火墙作为第一步。代理绕过说明、Windows TUN 常见问题

关闭系统代理,连接却还在走节点

检查 TUN 是否仍开启,以及应用自己的代理设置是否仍生效。想停用本客户端的接管,应同时处理实际启用的入口,并重新建立连接。关闭窗口可能只是把客户端收进托盘,也不等于退出。

07 TUN 能接管流量,DNS 仍要单独检查

访问网站的连接和解析域名的查询,可能走不同路径。TUN 已经开启,并不能直接推出“DNS 一定经过节点”。普通 DNS 是否被接管、应用是否使用独立的加密 DNS,以及解析服务连接走直连还是代理,都需要分别看。

例如,浏览器使用 DoH 时,查询本身是加密的 HTTPS 连接。它可能经 TUN 进入内核,但不会仅因一条针对 53 端口的 DNS 劫持设置,就自动变成 Mihomo 内置 DNS 处理的查询。相关字段和平台差异见Mihomo TUN 配置。

想继续检查解析路径,可以阅读DNS 防泄漏配置与验证。日常排查时,先确认应用连接进入了哪里,再看它选了什么出口,最后补上 DNS 这条路径,通常比不断切换“系统代理、TUN、全局”更有效。

diff --git a/docs/content/tutorials/system-proxy-tun.md b/docs/content/tutorials/system-proxy-tun.md new file mode 100644 index 00000000..44dc4add --- /dev/null +++ b/docs/content/tutorials/system-proxy-tun.md @@ -0,0 +1,103 @@ +浏览器能打开网页,终端却一直超时;已经切到“全局”,游戏还是连不上;打开 TUN 后能用了,又担心所有网站都被送到国外。遇到这些情况,先分清两件事:**流量有没有进入代理客户端,以及进入以后走哪个出口。** + +系统代理和 TUN 主要解决第一件事,规则、全局和直连模式主要解决第二件事。本文以 Clash Verge Rev 和 Mihomo 桌面客户端为例,说明它们的区别、适用场景和检查方法。 + + + +

01 系统代理:让应用按设置转交请求

+ +打开 Clash Verge Rev 的“系统代理”,客户端会修改操作系统的代理设置,把代理地址指向本机正在监听的端口。愿意读取并遵循这项设置的应用,就会把相应请求交给客户端处理。浏览器通常可以通过这种方式使用代理。[官方快速入门](https://www.clashverge.dev/guide/quickstart.html) + +这里的关键是“应用遵循设置”。有的软件读取系统设置,有的软件使用自己的代理配置,还有的软件直接建立连接。同一台电脑上,浏览器正常、另一个应用不走代理,并不矛盾。 + +
图 1 · 系统代理依赖应用配合
应用读取设置使用系统指定的代理
本机代理端口请求进入 Mihomo
匹配出口直连或代理节点
不遵循系统代理的应用:仍按自己的网络设置连接,不会仅因这个开关而进入 Mihomo。
这也解释了为什么“浏览器能用”不能代表电脑上每个应用都已经走代理。
+ +如果应用提供 HTTP 或 SOCKS 代理选项,可以单独指向客户端的本机端口。地址通常是 127.0.0.1,端口应查看客户端当前设置,不要照抄别人的数字;HTTP、SOCKS 和混合端口也要对应正确。 + +终端工具同样需要看各自支持什么。以 Linux 上的 curl 为例,可以先用[单条命令指定代理的方法](/a/m174.html#terminal)检查,不必为了一个工具马上接管整台电脑。 + +

02 TUN:通过虚拟网卡接收流量

+ +TUN 会创建虚拟网络接口,并通过路由把符合接管条件的 IP 流量交给内核。应用不必先学会使用 HTTP 或 SOCKS 代理,因此它常用于系统代理无法覆盖的程序。Mihomo 可以处理通过 TUN 进入的 TCP、UDP 流量,但最终能否完成连接,还取决于配置、节点和目标服务。[官方名词解释](https://www.clashverge.dev/guide/term.html) + +
图 2 · TUN 在网络路由这一层接管
应用发起连接无需读取系统代理
系统路由 → TUN进入虚拟网卡
Mihomo 处理再决定实际出口
被排除的地址、接口或其他未进入 TUN 的连接,仍可能走原来的网络路径。
TUN 扩大了接管范围,但开关亮着不等于每一条连接都已被接管。
+ +TUN 也有接管范围。自动路由、排除网段、IPv6 设置及其他 VPN 的路由,都可能影响实际路径。例如,把某个局域网网段排除在 TUN 之外,就是让它绕过这层接管;这与连接进入 Mihomo 后命中 DIRECT 规则不同。[Mihomo TUN 配置](https://wiki.metacubex.one/config/inbound/tun/)、[代理绕过说明](https://www.clashverge.dev/guide/bypass.html) + +日常使用图形客户端时,优先使用它提供的 TUN 设置。建立网卡和修改路由需要相应权限;Clash Verge Rev 的服务模式可让具有权限的后台服务启动内核,不代表必须一直以管理员身份运行整个界面。[服务模式说明](https://www.clashverge.dev/guide/term.html) + +

03 “全局”和 TUN 不是同一个维度

+ +把“规则”改成“全局”,改变的是进入内核后的出口选择。一个完全没有进入客户端的应用,不会因为切到全局就自动被接管。 + +反过来,开启 TUN 也不要求使用全局模式。**TUN + 规则模式**可以接管更多应用,同时继续按规则让部分连接直连、部分连接使用节点。[规则与全局模式说明](https://www.clashverge.dev/guide/term.html) + +
图 3 · 先进入客户端,再决定去哪里
第一步:接管系统代理 / 应用代理 / TUN
第二步:选择出口规则 / 全局 / 直连
第三步:建立连接本地网络或所选节点
排错也按这个顺序进行:先找有没有进入,再看实际出口,最后判断线路是否可用。
+ +| 常见组合 | 实际含义 | +|---|---| +| 系统代理 + 规则 | 遵循系统代理的请求进入客户端,再按当前配置分流 | +| 系统代理 + 全局 | 进入内核的普通业务连接使用全局策略;未被接管的应用仍可能绕过 | +| TUN + 规则 | 被 TUN 接管的连接按规则选择出口,并非全部使用代理节点 | +| TUN + 全局 | 被接管的普通业务连接使用全局策略;仍需查看所选策略是否为可用节点 | + +一个具体例子:浏览器和下载工具访问同一域名,浏览器连接记录里显示了节点,下载工具却没有记录。此时应优先检查下载工具的代理设置或接管方式;反复切换全局,通常没有解决前面的缺口。 + +

04 按应用需求选择,不必一开始全部打开

+ +| 你要完成的事 | 可以先这样做 | +|---|---| +| 主要浏览网页,常用软件已经正常 | 使用系统代理 + 规则模式 | +| 只有一个应用不跟随系统设置,且自带代理选项 | 给该应用配置正确的本机代理端口 | +| 多个应用不支持代理设置,希望统一处理 | 考虑 TUN + 规则模式,再逐个检查所需应用 | +| 游戏或语音涉及 UDP | 检查 TUN 接管,同时确认所选节点支持所需 UDP 转发 | +| 需要同时访问公司 VPN、NAS 或局域网设备 | 先明确这些连接的路径,再设置绕过或直连,避免盲目全局接管 | + +**TUN 不是加速档位。** 游戏登录网页能打开,不代表游戏数据传输已经正常;节点对网页可用,也不代表它能承载所需的 UDP。选择方式要看应用连接是否按预期工作,而不是哪个开关听起来更强。 + +系统代理和 TUN 可以同时存在,但两个开关都开不代表效果翻倍。应用主动交给本机端口的请求,本来就已进入客户端;其他连接可能由 TUN 接管。排错时,先明确正在验证哪条路径,比同时改动多个设置更容易找到原因。 + +

05 从系统代理切到 TUN,怎样确认有效

+ +先确保客户端已经导入配置、选中可用节点,并完成基本连接。尚未完成这一步,可以按对应平台的教程操作:[Windows](/a/clash-verge-rev-windows.html#enable)、[Mac](/a/m173.html#enable)、[Linux](/a/m174.html#connect)。 + +1. **记录原来的设置。** 包括系统代理、TUN 开关和当前代理组。保持订阅、节点和规则模式不变,便于对比。 +2. **按客户端提示启用服务和 TUN。** 若开关自动关闭或提示权限错误,先处理服务状态与具体错误,不要继续叠加 DNS、协议栈等改动。 +3. **排除其他入口的干扰。** 若要确认某个应用是否由 TUN 接管,暂时关闭本客户端的系统代理,并检查该应用是否另设了代理;有的话记录原值,再临时停用。只关闭系统代理,不能排除应用自己的代理设置。 +4. **让目标应用发起新连接。** 重连应用或重新打开目标内容,避免只观察缓存页面和原有长连接。 +5. **查看连接记录。** 按域名、目标 IP 或可用的进程信息定位请求,查看匹配规则、出口策略,以及界面或日志提供的入站信息。应走节点的请求如果显示 DIRECT,需要回到分流规则检查。 +6. **检查日常需要的本地服务。** 包括局域网设备、公司内网等;确认没有因路由变化失去访问能力,再保留这套设置。 + +关掉系统代理后应用仍能联网,只能说明它不依赖刚才关闭的那项设置。还要结合新连接记录和实际出口,才能判断 TUN 是否按预期接管;应用本来就能直连时,单凭“能打开”尤其容易误判。 + +如果切换后异常,先关闭 TUN,恢复刚才记录的系统代理和应用设置,让连接回到原先可用的状态,再按下一节定位。 + +

06 按现象定位,少做无关改动

+ +### 浏览器能用,终端或另一个应用不能用 + +先检查该应用是否跟随系统代理,或者是否需要独立配置。观察它发起新请求时,客户端有没有相应连接记录。记录里没有出现时,先清除列表筛选、重试并查看日志,排查接管问题;已经出现时,再看命中的规则和实际出口。 + +### 开了 TUN,流量仍显示 DIRECT + +DIRECT 表示这条连接由客户端直连,并不等于 TUN 没有工作。检查它是否命中了局域网、国内地址等直连规则,或代理组本身选中了 DIRECT。需要改变的是对应出口策略,而不是反复重启虚拟网卡。 + +### 网页正常,游戏或语音仍然失败 + +把登录请求和实时数据连接分开看。后者可能使用不同的地址、端口和 UDP。确认目标连接已进入客户端,再检查节点是否支持相关转发;网页测试成功不能代替这项检查。 + +### 一开 TUN,局域网、公司 VPN 或整个网络就异常 + +先恢复原先可用的方式,再检查路由重叠、网段冲突和客户端日志。系统代理绕过、TUN 路由排除与内核 DIRECT 规则各自发生在不同位置,不应混为一谈。不要把删除网卡或关闭全部防火墙作为第一步。[代理绕过说明](https://www.clashverge.dev/guide/bypass.html)、[Windows TUN 常见问题](https://www.clashverge.dev/faq/windows.html) + +### 关闭系统代理,连接却还在走节点 + +检查 TUN 是否仍开启,以及应用自己的代理设置是否仍生效。想停用本客户端的接管,应同时处理实际启用的入口,并重新建立连接。关闭窗口可能只是把客户端收进托盘,也不等于退出。 + +

07 TUN 能接管流量,DNS 仍要单独检查

+ +访问网站的连接和解析域名的查询,可能走不同路径。TUN 已经开启,并不能直接推出“DNS 一定经过节点”。普通 DNS 是否被接管、应用是否使用独立的加密 DNS,以及解析服务连接走直连还是代理,都需要分别看。 + +例如,浏览器使用 DoH 时,查询本身是加密的 HTTPS 连接。它可能经 TUN 进入内核,但不会仅因一条针对 53 端口的 DNS 劫持设置,就自动变成 Mihomo 内置 DNS 处理的查询。相关字段和平台差异见[Mihomo TUN 配置](https://wiki.metacubex.one/config/inbound/tun/)。 + +想继续检查解析路径,可以阅读[DNS 防泄漏配置与验证](/a/mihomo-dns-leak.html#dns-2)。日常排查时,先确认应用连接进入了哪里,再看它选了什么出口,最后补上 DNS 这条路径,通常比不断切换“系统代理、TUN、全局”更有效。 diff --git a/docs/content/tutorials/v2rayng-android.html b/docs/content/tutorials/v2rayng-android.html new file mode 100644 index 00000000..4579677c --- /dev/null +++ b/docs/content/tutorials/v2rayng-android.html @@ -0,0 +1 @@ +

在 Android 手机上使用本站的免费节点,可以先把 v2ray 订阅导入 v2rayNG,再选择一个节点连接。订阅负责提供节点列表,客户端负责建立连接;以后节点变化时,通常刷新订阅就能重新获取列表。

这篇教程从安装开始,带你完成第一次连接,再讲怎样更新订阅、换节点,以及连接失败时先检查哪里。

从安装到第一次连接
安装 v2rayNG选择适合手机的 APK
→
添加订阅保存地址,再更新列表
→
选择节点点选一条线路
→
启动并验证允许 VPN,打开网页
图 1 · 操作流程示意。出现节点列表后,还需要启动连接。

01 下载并安装 v2rayNG

打开 v2rayNG 官方发行页,展开 Assets,下载以 .apk 结尾的安装包。安装包架构按下表选择;后续更新也可使用这个官方入口。

手机或设备类型选择哪个包
近几年的常见 Android 手机文件名含 arm64-v8a 的标准版
不确定处理器架构文件名含 universal 的通用版,体积较大
已确认是 32 位 ARM 的旧设备文件名含 armeabi-v7a 的版本
x86 架构设备或模拟器按实际架构选择 x86 / x86_64,或通用版

完整的包名说明见官方发布文件介绍。Source code 是源码,.sig 是签名文件,都不是用来直接安装的 APK。

下载后打开 APK,按手机提示完成安装。若系统要求允许当前浏览器或文件管理器“安装未知应用”,按提示为本次安装开启该权限即可。v2rayNG 2.3.11 的最低系统要求为 Android 7.0;通用包只能解决架构选择问题,不能让过旧的系统满足版本要求。

02 从本站取得适用的订阅

进入本站免费节点页面,打开较新的一篇分享,找到标有 v2ray / shadowrocket / 小火箭 的订阅地址。v2rayNG 使用其中的 v2ray 订阅;同一篇文章里的 Clash / Mihomo 配置可按 Clash Meta for Android 教程导入;sing-box 配置也有对应客户端,导入时要认准格式。

复制的是订阅链接本身,不是免费节点文章的网址。文章网址用于阅读说明,订阅链接才是客户端获取节点列表的入口。

免费节点的可用性会变化,较新的分享也不保证每个节点都能连接。先导入并尝试几条线路,后面再按实际使用情况保留合适的节点。

03 添加订阅,再更新出节点列表

打开 v2rayNG,按下面的顺序操作。以下步骤以 2.3.11 为例;其他版本可按同名选项操作。

  1. 打开左上角导航菜单,进入 订阅分组。
  2. 点击添加按钮,在“备注”中填写一个容易辨认的名字,例如“本站免费节点”。
  3. 在 URL 一栏粘贴刚才复制的订阅地址,保持“启用更新”打开,保存。
  4. 回到订阅分组列表,点击顶部的 更新订阅 按钮。
  5. 若出现更新选项,勾选“更新订阅”并确认;首次导入先完成这一项即可。
  6. 等待更新完成,回到主界面并查看对应分组,确认节点列表已经出现。
订阅导入的关键是两步
保存订阅地址告诉软件“去哪里获取”
→
执行更新订阅下载并读取节点信息
→
主界面出现节点现在才可以选择线路
图 2 · 功能关系示意,并非软件截图。只保存分组、没有更新,是列表为空时首先要检查的地方。

添加订阅时,“URL”虽然标为可选,但本教程需要通过网络获取节点,因此这里要填写地址。其他高级字段保持原样,不必填写请求头、过滤表达式或代理链。

如果拿到的是一条 vmess://、vless://、trojan:// 等节点分享链接,可以复制后使用主界面的 添加配置 → 从剪贴板导入。这会添加单独的节点;想随分享更新一整组节点,仍应使用前面的订阅方式。

04 选择节点,启动连接

在主界面点选一个节点,确认它已处于选中状态,再点击右下方的启动按钮。2.3.11 使用播放形状的启动图标,运行后会切换为停止图标。

首次启动时,Android 通常会弹出 VPN 连接请求,确认应用名称为 v2rayNG 后允许。这里的 VPN 权限用于让客户端接管手机流量,不需要为此给手机 Root。

如果另一个代理或使用本地 VPN 的过滤工具正在运行,先停止它再连接 v2rayNG。同一个 Android 用户空间通常只能有一个活动 VPN 服务,后来启动的应用可能把前一个断开。

首次连接先保持应用默认设置,暂时不用修改 DNS、路由或分应用名单。等基础连接成功后,再按需要调整流量范围。

05 确认节点真的能用

看到 VPN 标识,说明手机已经建立了本地接管通道;节点是否能访问外网,还要继续检查。

先在客户端使用 测试真连接延迟,或者点击底部的连接测试区域检查当前节点。然后打开浏览器,访问一个你实际需要使用的网站,再尝试相应的应用。

看到的结果可以说明什么
节点列表已经出现订阅已成功读取,尚不能说明节点可用
VPN 标识或停止按钮出现客户端服务正在运行
真连接测试返回延迟对测试目标的连接成功
实际网页或应用正常使用本次需要的访问已完成

测试地址和你要访问的服务可能不同,因此延迟数字只作参考。如果某个节点一直超时,先换另一条,再重复测试和网页访问。不要只看最低延迟就认定它适合所有网站。

06 平时怎样更新、换节点和断开

更新列表: 回到“订阅分组”执行更新。本站分享可能使用按日期变化的订阅地址;刷新旧地址只会重新读取旧地址里的内容,不会自动切换到新一期。如果这一批节点都失效了,回到免费节点页面查看较新的分享,在原分组中替换 URL、保存后再次更新。

更换节点: 在主界面选中另一条节点。如果不确定当前连接是否已经切换,可以先停止,再选节点并重新启动,然后重新打开网页验证。

暂停使用: 点击停止按钮,确认服务结束。返回桌面或关闭主窗口并不等于断开连接。

如果你也需要在 Windows 电脑上使用本站节点,可以接着看 Clash Verge Rev 入门教程;电脑端按那篇文章选取 Clash / Mihomo 格式的订阅。

07 遇到问题,从出现问题的那一步查起

安装包无法安装。 先核对系统版本和 APK 架构,确认下载已经完成。如果是覆盖安装时提示签名不一致,不要直接卸载:先保存已有配置,再确认新旧安装包是否来自同一发布渠道。

保存了订阅,主界面仍然是空的。 检查 URL 是否确实填入、分组是否启用更新,然后手动执行一次更新。更新后也要查看正确的分组,避免搜索或筛选条件隐藏了节点。

更新失败,或者提示没有可导入的配置。 检查是否误复制了文章网址、遗漏链接字符,或选择了 Clash / sing-box 格式。地址正确但仍失败时,确认手机本身能上网,再尝试本站较新的 v2ray 订阅。

已经启动,但所有节点都超时。 先停止 v2rayNG,确认普通网络可用;再换节点重连。如果只有某一批节点不可用,优先更换订阅来源或分享批次,不必反复重装软件。

浏览器正常,某个应用不正常。 若之前启用了分应用代理,检查那个应用是否在预期接管范围内;若没有开启,再换节点测试该服务,区分应用问题和节点对特定服务不可用。

锁屏一段时间后断开。 先观察 v2rayNG 服务是否仍在运行。如果是被系统结束,再到手机的应用电池管理中允许它后台运行;菜单名称因手机厂商而异。

diff --git a/docs/content/tutorials/v2rayng-android.md b/docs/content/tutorials/v2rayng-android.md new file mode 100644 index 00000000..02312792 --- /dev/null +++ b/docs/content/tutorials/v2rayng-android.md @@ -0,0 +1,98 @@ +在 Android 手机上使用本站的免费节点,可以先把 v2ray 订阅导入 v2rayNG,再选择一个节点连接。订阅负责提供节点列表,客户端负责建立连接;以后节点变化时,通常刷新订阅就能重新获取列表。 + +这篇教程从安装开始,带你完成第一次连接,再讲怎样更新订阅、换节点,以及连接失败时先检查哪里。 + +
从安装到第一次连接
安装 v2rayNG选择适合手机的 APK
→
添加订阅保存地址,再更新列表
→
选择节点点选一条线路
→
启动并验证允许 VPN,打开网页
图 1 · 操作流程示意。出现节点列表后,还需要启动连接。
+ + + +

01 下载并安装 v2rayNG

+ +打开 [v2rayNG 官方发行页](https://github.com/2dust/v2rayNG/releases/latest),展开 **Assets**,下载以 `.apk` 结尾的安装包。安装包架构按下表选择;后续更新也可使用这个官方入口。 + +| 手机或设备类型 | 选择哪个包 | +|---|---| +| 近几年的常见 Android 手机 | 文件名含 `arm64-v8a` 的标准版 | +| 不确定处理器架构 | 文件名含 `universal` 的通用版,体积较大 | +| 已确认是 32 位 ARM 的旧设备 | 文件名含 `armeabi-v7a` 的版本 | +| x86 架构设备或模拟器 | 按实际架构选择 `x86` / `x86_64`,或通用版 | + +完整的包名说明见[官方发布文件介绍](https://github.com/2dust/v2rayNG/wiki/Release-files-introduction-for-Android)。`Source code` 是源码,`.sig` 是签名文件,都不是用来直接安装的 APK。 + +下载后打开 APK,按手机提示完成安装。若系统要求允许当前浏览器或文件管理器“安装未知应用”,按提示为本次安装开启该权限即可。v2rayNG 2.3.11 的最低系统要求为 **Android 7.0**;通用包只能解决架构选择问题,不能让过旧的系统满足版本要求。 + +

02 从本站取得适用的订阅

+ +进入本站[免费节点页面](/freenode),打开较新的一篇分享,找到标有 **v2ray / shadowrocket / 小火箭** 的订阅地址。v2rayNG 使用其中的 v2ray 订阅;同一篇文章里的 Clash / Mihomo 配置可按 [Clash Meta for Android 教程](/a/m169.html#import)导入;sing-box 配置也有对应客户端,导入时要认准格式。 + +复制的是订阅链接本身,不是免费节点文章的网址。文章网址用于阅读说明,订阅链接才是客户端获取节点列表的入口。 + +免费节点的可用性会变化,较新的分享也不保证每个节点都能连接。先导入并尝试几条线路,后面再按实际使用情况保留合适的节点。 + +

03 添加订阅,再更新出节点列表

+ +打开 v2rayNG,按下面的顺序操作。以下步骤以 2.3.11 为例;其他版本可按同名选项操作。 + +1. 打开左上角导航菜单,进入 **订阅分组**。 +2. 点击添加按钮,在“备注”中填写一个容易辨认的名字,例如“本站免费节点”。 +3. 在 **URL** 一栏粘贴刚才复制的订阅地址,保持“启用更新”打开,保存。 +4. 回到订阅分组列表,点击顶部的 **更新订阅** 按钮。 +5. 若出现更新选项,勾选“更新订阅”并确认;首次导入先完成这一项即可。 +6. 等待更新完成,回到主界面并查看对应分组,确认节点列表已经出现。 + +
订阅导入的关键是两步
保存订阅地址告诉软件“去哪里获取”
→
执行更新订阅下载并读取节点信息
→
主界面出现节点现在才可以选择线路
图 2 · 功能关系示意,并非软件截图。只保存分组、没有更新,是列表为空时首先要检查的地方。
+ +添加订阅时,“URL”虽然标为可选,但本教程需要通过网络获取节点,因此这里要填写地址。其他高级字段保持原样,不必填写请求头、过滤表达式或代理链。 + +如果拿到的是一条 `vmess://`、`vless://`、`trojan://` 等节点分享链接,可以复制后使用主界面的 **添加配置 → 从剪贴板导入**。这会添加单独的节点;想随分享更新一整组节点,仍应使用前面的订阅方式。 + +

04 选择节点,启动连接

+ +在主界面点选一个节点,确认它已处于选中状态,再点击右下方的启动按钮。2.3.11 使用播放形状的启动图标,运行后会切换为停止图标。 + +首次启动时,Android 通常会弹出 VPN 连接请求,确认应用名称为 v2rayNG 后允许。这里的 VPN 权限用于让客户端接管手机流量,不需要为此给手机 Root。 + +如果另一个代理或使用本地 VPN 的过滤工具正在运行,先停止它再连接 v2rayNG。同一个 Android 用户空间通常只能有一个活动 VPN 服务,后来启动的应用可能把前一个断开。 + +首次连接先保持应用默认设置,暂时不用修改 DNS、路由或分应用名单。等基础连接成功后,再按需要调整流量范围。 + +

05 确认节点真的能用

+ +看到 VPN 标识,说明手机已经建立了本地接管通道;节点是否能访问外网,还要继续检查。 + +先在客户端使用 **测试真连接延迟**,或者点击底部的连接测试区域检查当前节点。然后打开浏览器,访问一个你实际需要使用的网站,再尝试相应的应用。 + +| 看到的结果 | 可以说明什么 | +|---|---| +| 节点列表已经出现 | 订阅已成功读取,尚不能说明节点可用 | +| VPN 标识或停止按钮出现 | 客户端服务正在运行 | +| 真连接测试返回延迟 | 对测试目标的连接成功 | +| 实际网页或应用正常使用 | 本次需要的访问已完成 | + +测试地址和你要访问的服务可能不同,因此延迟数字只作参考。如果某个节点一直超时,先换另一条,再重复测试和网页访问。不要只看最低延迟就认定它适合所有网站。 + +

06 平时怎样更新、换节点和断开

+ +**更新列表:** 回到“订阅分组”执行更新。本站分享可能使用按日期变化的订阅地址;刷新旧地址只会重新读取旧地址里的内容,不会自动切换到新一期。如果这一批节点都失效了,回到[免费节点页面](/freenode)查看较新的分享,在原分组中替换 URL、保存后再次更新。 + +**更换节点:** 在主界面选中另一条节点。如果不确定当前连接是否已经切换,可以先停止,再选节点并重新启动,然后重新打开网页验证。 + +**暂停使用:** 点击停止按钮,确认服务结束。返回桌面或关闭主窗口并不等于断开连接。 + +如果你也需要在 Windows 电脑上使用本站节点,可以接着看 [Clash Verge Rev 入门教程](/a/clash-verge-rev-windows.html#install);电脑端按那篇文章选取 Clash / Mihomo 格式的订阅。 + +

07 遇到问题,从出现问题的那一步查起

+ +**安装包无法安装。** 先核对系统版本和 APK 架构,确认下载已经完成。如果是覆盖安装时提示签名不一致,不要直接卸载:先保存已有配置,再确认新旧安装包是否来自同一发布渠道。 + +**保存了订阅,主界面仍然是空的。** 检查 URL 是否确实填入、分组是否启用更新,然后手动执行一次更新。更新后也要查看正确的分组,避免搜索或筛选条件隐藏了节点。 + +**更新失败,或者提示没有可导入的配置。** 检查是否误复制了文章网址、遗漏链接字符,或选择了 Clash / sing-box 格式。地址正确但仍失败时,确认手机本身能上网,再尝试本站较新的 v2ray 订阅。 + +**已经启动,但所有节点都超时。** 先停止 v2rayNG,确认普通网络可用;再换节点重连。如果只有某一批节点不可用,优先更换订阅来源或分享批次,不必反复重装软件。 + +**浏览器正常,某个应用不正常。** 若之前启用了分应用代理,检查那个应用是否在预期接管范围内;若没有开启,再换节点测试该服务,区分应用问题和节点对特定服务不可用。 + +**锁屏一段时间后断开。** 先观察 v2rayNG 服务是否仍在运行。如果是被系统结束,再到手机的应用电池管理中允许它后台运行;菜单名称因手机厂商而异。 + +
参考资料:官方 2.3.11 发行页、Android 官方文档。
diff --git a/docs/content/tutorials/verge-linux.html b/docs/content/tutorials/verge-linux.html new file mode 100644 index 00000000..5c635888 --- /dev/null +++ b/docs/content/tutorials/verge-linux.html @@ -0,0 +1 @@ +

这篇教程适用于带桌面环境的 Linux 电脑,以 Ubuntu / Debian 和 Fedora 为例,完成 Clash Verge Rev 安装、订阅导入与第一次连接。只有 SSH 终端的服务器不属于这里的使用场景:Clash Verge Rev 是图形客户端,需要桌面环境。

Linux 安装前的三个条件
有桌面环境能够打开图形应用
→
选对包格式Debian 系用 DEB,Fedora 用 RPM
→
匹配 CPU 架构x86_64 或 ARM 等
图 1 · 包格式和 CPU 架构是两回事;安装失败时,先核对这两项。

01 找到适合发行版和架构的安装包

从Clash Verge Rev 官方发行页下载正式版。在终端执行下面的只读命令,确认机器架构:

uname -m
输出 / 系统下载时的选择
x86_64,Ubuntu / Debianamd64.deb
aarch64,Ubuntu / Debianarm64.deb
x86_64,Fedorax86_64.rpm
aarch64,Fedoraaarch64.rpm

amd64 也适用于使用同一架构的 Intel 处理器,不是“只能在 AMD 电脑上安装”。其他架构需要单独核对发行文件,不能只把下载文件改名。

以下以 v2.5.8、x86_64 电脑为例。在文件管理器中打开下载文件所在目录,再在该目录打开终端。使用较新版本时,将文件名换成实际下载的名字。

Ubuntu / Debian:

sudo apt install ./Clash.Verge_2.5.8_amd64.deb

Fedora:

sudo dnf install ./Clash.Verge-2.5.8-1.x86_64.rpm

只执行适合自己发行版的一条命令。前面的 ./ 表示安装当前目录里的文件;包管理器会尝试处理依赖,确认安装计划后再继续。完成后从应用菜单启动 Clash Verge Rev,正常使用时不必用 sudo 启动整个图形程序。

旧系统遇到 WebKit 等依赖缺失时,先查官方 Linux FAQ和发行版支持情况。官方文档特别指出 Ubuntu 20.04 的依赖问题,并建议使用较新的系统;不要强行混入其他发行版的软件源来凑依赖。

02 导入 Clash / Mihomo 免费订阅

在本站免费节点页面打开较新的分享,复制其中的 Clash / Mihomo 订阅地址。回到客户端:

  1. 进入“订阅”,粘贴链接并导入。
  2. 等待配置下载完成,选中这张订阅卡片。
  3. 进入“代理”,确认已出现代理组和节点。
  4. 使用规则模式,在处理代理流量的组内手动选择一条节点。

订阅卡片已保存,不代表它已经成为当前配置。看不到节点时,先检查是否选中卡片、链接格式是否正确;普通文章网址、v2ray 订阅与 sing-box 配置不能直接当成 Clash 配置。

免费节点可能随时失效。延迟测试可帮助排除超时线路,但最终仍要打开实际需要的网站验证。

03 先让浏览器通过系统代理连接

在客户端设置中开启 系统代理,先保持 TUN 关闭,然后重新发起浏览器访问。系统代理是否被应用采用,取决于桌面环境和应用本身;Firefox 等浏览器也可能设置了自己的代理选项,需要确认其使用系统代理或正确的手动代理。

同时打开客户端“连接”页面,观察刚才请求的域名、匹配规则与出口。规则模式可能让部分网站走 DIRECT,所以“网页打开了”不一定证明它经过了远端节点。

浏览器能用,不代表终端自动跟随
桌面应用是否读取桌面代理设置?
→
客户端本机端口接收连接并按规则分流
→
远端节点或直连在连接记录中核对
命令行工具通常需要自己的代理参数或环境变量;TUN 则是另一种接管方式。
图 2 · 系统代理、命令行代理和 TUN 是不同的流量入口,不能只看一个开关判断全部程序。

04 需要终端访问时,先做一次单独验证

在客户端设置中查看实际的 混合端口或 SOCKS 端口。以下命令只给这一条 curl 请求指定代理,不会替你修改终端启动文件或全局网络设置。

把命令里的 PORT 替换成刚才看到的数字,再运行:

curl --noproxy "" --proxy socks5h://127.0.0.1:PORT https://example.com/

127.0.0.1 指当前电脑;socks5h 让 curl 把目标域名交给 SOCKS 代理处理;--noproxy "" 避免已有的绕过列表让这次请求跳过指定代理。客户端仍会根据自己的规则决定最终走节点还是直连。

成功返回示例网页,说明这一条请求能通过该本机代理入口完成。它不证明所有终端程序已经使用代理,也不证明所有 DNS 查询都被接管。验证需要的真实服务时,再替换目标网址,并结合客户端连接记录判断。

常用工具如 Git、包管理器和下载器各有自己的代理设置。只有确认需要长期使用后,再按对应工具文档配置;不要为了临时试一次,就把一组不明代理变量永久写入 shell 配置。

05 更新节点与停止使用

情况操作
某一条节点超时换其他节点,重新发起访问
一批节点都失效刷新订阅,并回本站查看较新的免费资源
浏览器正常,某应用不通检查该应用的代理设置,再判断是否需要TUN
暂时停用关闭系统代理;已开启TUN时也关闭它,再退出客户端
退出后仍有应用报代理连接失败检查该应用、桌面设置或shell环境是否残留已停止的本机代理地址

06 按故障所在的环节排查

安装时找不到文件。 核对终端当前目录和完整文件名,尤其是版本号、大小写及 .deb / .rpm 后缀。不要把网页上的示例文件名直接套到不同版本。

应用打不开、白屏或报 WebKit / GBM 错误。 先记录完整错误、发行版版本、显卡和 Wayland / X11 会话类型,再对照官方 Linux FAQ。显示渲染错误与节点连接错误是不同问题,不需要通过反复换订阅处理。

系统代理开启后,终端还是直连。 先用上一节的单条 curl 请求验证端口,再检查具体工具是否有自己的代理选项。桌面开关通常不会自动给所有 shell 进程设置代理变量。

需要接管更多应用或检查 DNS。 完成基本连接后,再按客户端要求配置服务模式与TUN权限,并验证实际效果。DNS路径可继续看DNS 防泄漏配置与验证,其中的片段需要结合Linux实际网络环境调整。

如果同样要在 Mac 上使用,可先看Mac 客户端下载指南,再按对应平台步骤操作。

diff --git a/docs/content/tutorials/verge-linux.md b/docs/content/tutorials/verge-linux.md new file mode 100644 index 00000000..12b9f12e --- /dev/null +++ b/docs/content/tutorials/verge-linux.md @@ -0,0 +1,101 @@ +这篇教程适用于带桌面环境的 Linux 电脑,以 Ubuntu / Debian 和 Fedora 为例,完成 Clash Verge Rev 安装、订阅导入与第一次连接。只有 SSH 终端的服务器不属于这里的使用场景:Clash Verge Rev 是图形客户端,需要桌面环境。 + +
Linux 安装前的三个条件
有桌面环境能够打开图形应用
→
选对包格式Debian 系用 DEB,Fedora 用 RPM
→
匹配 CPU 架构x86_64 或 ARM 等
图 1 · 包格式和 CPU 架构是两回事;安装失败时,先核对这两项。
+ + + +

01 找到适合发行版和架构的安装包

+ +从[Clash Verge Rev 官方发行页](https://github.com/clash-verge-rev/clash-verge-rev/releases/latest)下载正式版。在终端执行下面的只读命令,确认机器架构: + +```sh +uname -m +``` + +| 输出 / 系统 | 下载时的选择 | +|---|---| +| `x86_64`,Ubuntu / Debian | `amd64.deb` | +| `aarch64`,Ubuntu / Debian | `arm64.deb` | +| `x86_64`,Fedora | `x86_64.rpm` | +| `aarch64`,Fedora | `aarch64.rpm` | + +`amd64` 也适用于使用同一架构的 Intel 处理器,不是“只能在 AMD 电脑上安装”。其他架构需要单独核对发行文件,不能只把下载文件改名。 + +以下以 **v2.5.8、x86_64 电脑**为例。在文件管理器中打开下载文件所在目录,再在该目录打开终端。使用较新版本时,将文件名换成实际下载的名字。 + +Ubuntu / Debian: + +```sh +sudo apt install ./Clash.Verge_2.5.8_amd64.deb +``` + +Fedora: + +```sh +sudo dnf install ./Clash.Verge-2.5.8-1.x86_64.rpm +``` + +只执行适合自己发行版的一条命令。前面的 `./` 表示安装当前目录里的文件;包管理器会尝试处理依赖,确认安装计划后再继续。完成后从应用菜单启动 Clash Verge Rev,正常使用时不必用 `sudo` 启动整个图形程序。 + +旧系统遇到 WebKit 等依赖缺失时,先查[官方 Linux FAQ](https://www.clashverge.dev/faq/linux.html)和发行版支持情况。官方文档特别指出 Ubuntu 20.04 的依赖问题,并建议使用较新的系统;不要强行混入其他发行版的软件源来凑依赖。 + +

02 导入 Clash / Mihomo 免费订阅

+ +在本站[免费节点页面](/freenode)打开较新的分享,复制其中的 **Clash / Mihomo** 订阅地址。回到客户端: + +1. 进入“订阅”,粘贴链接并导入。 +2. 等待配置下载完成,选中这张订阅卡片。 +3. 进入“代理”,确认已出现代理组和节点。 +4. 使用规则模式,在处理代理流量的组内手动选择一条节点。 + +订阅卡片已保存,不代表它已经成为当前配置。看不到节点时,先检查是否选中卡片、链接格式是否正确;普通文章网址、v2ray 订阅与 sing-box 配置不能直接当成 Clash 配置。 + +免费节点可能随时失效。延迟测试可帮助排除超时线路,但最终仍要打开实际需要的网站验证。 + +

03 先让浏览器通过系统代理连接

+ +在客户端设置中开启 **系统代理**,先保持 TUN 关闭,然后重新发起浏览器访问。系统代理是否被应用采用,取决于桌面环境和应用本身;Firefox 等浏览器也可能设置了自己的代理选项,需要确认其使用系统代理或正确的手动代理。 + +同时打开客户端“连接”页面,观察刚才请求的域名、匹配规则与出口。规则模式可能让部分网站走 `DIRECT`,所以“网页打开了”不一定证明它经过了远端节点。 + +
浏览器能用,不代表终端自动跟随
桌面应用是否读取桌面代理设置?
→
客户端本机端口接收连接并按规则分流
→
远端节点或直连在连接记录中核对
命令行工具通常需要自己的代理参数或环境变量;TUN 则是另一种接管方式。
图 2 · 系统代理、命令行代理和 TUN 是不同的流量入口,不能只看一个开关判断全部程序。
+ +

04 需要终端访问时,先做一次单独验证

+ +在客户端设置中查看实际的 **混合端口或 SOCKS 端口**。以下命令只给这一条 curl 请求指定代理,不会替你修改终端启动文件或全局网络设置。 + +把命令里的 `PORT` 替换成刚才看到的数字,再运行: + +```sh +curl --noproxy "" --proxy socks5h://127.0.0.1:PORT https://example.com/ +``` + +`127.0.0.1` 指当前电脑;`socks5h` 让 curl 把目标域名交给 SOCKS 代理处理;`--noproxy ""` 避免已有的绕过列表让这次请求跳过指定代理。客户端仍会根据自己的规则决定最终走节点还是直连。 + +成功返回示例网页,说明这一条请求能通过该本机代理入口完成。它不证明所有终端程序已经使用代理,也不证明所有 DNS 查询都被接管。验证需要的真实服务时,再替换目标网址,并结合客户端连接记录判断。 + +常用工具如 Git、包管理器和下载器各有自己的代理设置。只有确认需要长期使用后,再按对应工具文档配置;不要为了临时试一次,就把一组不明代理变量永久写入 shell 配置。 + +

05 更新节点与停止使用

+ +| 情况 | 操作 | +|---|---| +| 某一条节点超时 | 换其他节点,重新发起访问 | +| 一批节点都失效 | 刷新订阅,并回本站查看较新的免费资源 | +| 浏览器正常,某应用不通 | 检查该应用的代理设置,再判断是否需要TUN | +| 暂时停用 | 关闭系统代理;已开启TUN时也关闭它,再退出客户端 | +| 退出后仍有应用报代理连接失败 | 检查该应用、桌面设置或shell环境是否残留已停止的本机代理地址 | + +

06 按故障所在的环节排查

+ +**安装时找不到文件。** 核对终端当前目录和完整文件名,尤其是版本号、大小写及 `.deb` / `.rpm` 后缀。不要把网页上的示例文件名直接套到不同版本。 + +**应用打不开、白屏或报 WebKit / GBM 错误。** 先记录完整错误、发行版版本、显卡和 Wayland / X11 会话类型,再对照[官方 Linux FAQ](https://www.clashverge.dev/faq/linux.html)。显示渲染错误与节点连接错误是不同问题,不需要通过反复换订阅处理。 + +**系统代理开启后,终端还是直连。** 先用上一节的单条 curl 请求验证端口,再检查具体工具是否有自己的代理选项。桌面开关通常不会自动给所有 shell 进程设置代理变量。 + +**需要接管更多应用或检查 DNS。** 完成基本连接后,再按客户端要求配置服务模式与TUN权限,并验证实际效果。DNS路径可继续看[DNS 防泄漏配置与验证](/a/mihomo-dns-leak.html),其中的片段需要结合Linux实际网络环境调整。 + +如果同样要在 Mac 上使用,可先看[Mac 客户端下载指南](/a/m172.html#download),再按对应平台步骤操作。 + +
参考资料:安装文档、快速入门、curl官方手册。
diff --git a/docs/content/tutorials/verge-mac.html b/docs/content/tutorials/verge-mac.html new file mode 100644 index 00000000..84f1953a --- /dev/null +++ b/docs/content/tutorials/verge-mac.html @@ -0,0 +1 @@ +

这篇教程带你在 Mac 上安装 Clash Verge Rev,导入本站的 Clash / Mihomo 免费订阅,再通过浏览器完成第一次连接。整个过程先使用规则模式和系统代理,不需要一开始就修改 DNS 或编写分流规则。

如果还没确定安装包架构,先看Mac 客户端选择与下载指南。

Mac 首次连接路线
安装到应用程序选对 Apple 芯片 / Intel 包
→
导入并启用订阅取得节点与规则
→
选择线路规则模式与可用节点
→
开启系统代理打开网页验证
图 1 · 完成安装只是第一步,客户端还需要配置和流量入口。

01 下载 DMG,并安装到“应用程序”

打开官方发行页,选择正式版的 macOS .dmg。Apple M 系列芯片选择 aarch64,Intel Mac 选择 x64。当前官方安装要求为 macOS 12 及以上。

  1. 打开下载完成的 DMG。
  2. 将 Clash Verge 应用拖入“应用程序”文件夹。
  3. 等待复制完成,再从“应用程序”打开它。
  4. 若系统询问是否打开从互联网下载的应用,核对名称和来源后确认。

后续从“应用程序”启动即可,不必每次重新打开 DMG。升级已有安装时,先通过菜单栏菜单退出旧程序,再替换应用,避免仍运行旧版本。

如果 macOS 因开发者验证问题阻止打开,先确认安装包来自项目官方发行页,再按 Apple 的应用打开说明查看“系统设置 → 隐私与安全性”中针对该应用的提示。提示应用会损害电脑时,应停止并核查来源;不用关闭整个系统的安全检查来完成普通安装。

02 导入本站订阅并选为当前配置

打开本站免费节点页面,选择较新的一篇分享,复制 Clash / Mihomo 订阅地址。复制后回到 Clash Verge Rev:

  1. 进入“订阅”页面。
  2. 在订阅地址输入框中粘贴链接,点击导入。
  3. 等待订阅卡片出现,选择它作为当前配置。
  4. 进入“代理”页面,确认已经出现代理组和节点。
Clash Verge Rev 订阅导入界面示例
图 2 · 官方文档中的订阅导入示例,展示输入框和配置卡片的关系;界面可能因版本而异。来源:官方快速入门。

如果保存了订阅却没有节点,先检查卡片是否已启用,再检查地址是否返回 Clash 配置。文章网页、v2ray 订阅和 sing-box 配置不能仅通过改文件后缀变成 Clash 配置。

03 选规则模式和一个手动节点

在代理页使用 规则模式,找到处理普通代理流量的代理组,手动选一条节点。组名来自订阅,可能是“节点选择”“代理”或其他名称。

初次使用先手动选,方便知道当前线路是哪一条。若提供延迟测试,可以用它筛掉持续超时的节点,但仍要用实际访问验证。DIRECT 表示直连,选择它不会通过代理节点。

规则模式会依据配置决定哪些连接走节点、哪些直连;全局模式则使用全局策略组。切换全局并不能自动接管所有应用,它与下一步的系统代理解决的是不同问题。

04 开启系统代理

在客户端设置中找到 系统代理 并开启。若 macOS 为修改网络设置弹出授权提示,确认是本次客户端操作后按系统要求处理。首次连接可先保持 TUN 关闭。

系统代理能处理哪些连接?
遵循系统代理的应用将请求交给本机代理端口
→
Clash Verge Rev按规则选择直连或节点
→
目标网站实际访问确认结果
未使用系统代理的应用,需要检查自身代理设置;有进一步接管需求时,再了解 TUN。
图 3 · 规则决定“交进来的连接怎么走”,系统代理决定哪些应用会把连接交进来。

如果电脑上还有其他代理客户端,先关闭它们的系统代理和 TUN,避免多个程序反复修改同一套网络设置。

05 通过网页和连接记录确认

保持软件运行,重新打开一个希望通过节点访问的网站,再尝试实际需要的服务。可以同时查看客户端“连接”页面,找到刚才请求的域名,观察匹配规则和出口。

浏览器已能正常使用、某个应用仍不能连接时,先检查该应用是否遵循系统代理。不要一看到单个应用失败就认定整份订阅无效。

需要进一步了解 DNS 查询路径时,可以继续阅读 DNS 防泄漏配置与验证。其中的配置片段需要按当前客户端与平台调整,不是完成首次连接的必选步骤。

06 更新、暂停和退出

想做的事操作
换一条线路在当前代理组中选其他节点,再重新发起访问
更新节点列表刷新订阅;若旧批次已失效,回本站查看较新的订阅地址
暂停代理关闭系统代理;如果另行启用了TUN,也关闭它
完全退出通过菜单栏图标的退出选项结束程序

Mac 窗口左上角的红色关闭按钮可能只关闭窗口,后台进程仍在。判断是否断开时看代理开关和运行状态,不只看窗口是否消失。

07 常见问题

系统代理开关开了,浏览器仍不通。 先确认当前订阅和组内节点,再检查 macOS 当前网络服务的代理设置是否确实发生变化。权限提示未完成、其他客户端覆盖设置,都可能影响结果。

找不到窗口。 先从菜单栏图标恢复主窗口;如果之前使用过外接显示器,窗口可能保留了旧位置,可参考官方 macOS FAQ调整显示器布局后再打开。

退出以后普通网页也打不开。 到“系统设置 → 网络”中打开当前 Wi-Fi 或以太网的详情,检查“代理”是否残留指向本机已停止端口的手动设置。确认属于该客户端后再清理;如果使用过TUN,也先确认已关闭。

一定要开 TUN 吗? 浏览器通过系统代理能满足当前需求时,可以先这样使用。有应用接管需求再配置TUN,并留意它在macOS上可能调整系统DNS;不要把开关名称当成已经完成DNS泄漏验证。

参考资料:安装文档、订阅说明。
diff --git a/docs/content/tutorials/verge-mac.md b/docs/content/tutorials/verge-mac.md new file mode 100644 index 00000000..8aa64881 --- /dev/null +++ b/docs/content/tutorials/verge-mac.md @@ -0,0 +1,80 @@ +这篇教程带你在 Mac 上安装 Clash Verge Rev,导入本站的 Clash / Mihomo 免费订阅,再通过浏览器完成第一次连接。整个过程先使用规则模式和系统代理,不需要一开始就修改 DNS 或编写分流规则。 + +如果还没确定安装包架构,先看[Mac 客户端选择与下载指南](/a/m172.html#download)。 + +
Mac 首次连接路线
安装到应用程序选对 Apple 芯片 / Intel 包
→
导入并启用订阅取得节点与规则
→
选择线路规则模式与可用节点
→
开启系统代理打开网页验证
图 1 · 完成安装只是第一步,客户端还需要配置和流量入口。
+ + + +

01 下载 DMG,并安装到“应用程序”

+ +打开[官方发行页](https://github.com/clash-verge-rev/clash-verge-rev/releases/latest),选择正式版的 macOS `.dmg`。Apple M 系列芯片选择 `aarch64`,Intel Mac 选择 `x64`。当前官方安装要求为 macOS 12 及以上。 + +1. 打开下载完成的 DMG。 +2. 将 Clash Verge 应用拖入“应用程序”文件夹。 +3. 等待复制完成,再从“应用程序”打开它。 +4. 若系统询问是否打开从互联网下载的应用,核对名称和来源后确认。 + +后续从“应用程序”启动即可,不必每次重新打开 DMG。升级已有安装时,先通过菜单栏菜单退出旧程序,再替换应用,避免仍运行旧版本。 + +如果 macOS 因开发者验证问题阻止打开,先确认安装包来自项目官方发行页,再按 [Apple 的应用打开说明](https://support.apple.com/en-gb/102445)查看“系统设置 → 隐私与安全性”中针对该应用的提示。提示应用会损害电脑时,应停止并核查来源;不用关闭整个系统的安全检查来完成普通安装。 + +

02 导入本站订阅并选为当前配置

+ +打开本站[免费节点页面](/freenode),选择较新的一篇分享,复制 **Clash / Mihomo** 订阅地址。复制后回到 Clash Verge Rev: + +1. 进入“订阅”页面。 +2. 在订阅地址输入框中粘贴链接,点击导入。 +3. 等待订阅卡片出现,选择它作为当前配置。 +4. 进入“代理”页面,确认已经出现代理组和节点。 + +
Clash Verge Rev 订阅导入界面示例
图 2 · 官方文档中的订阅导入示例,展示输入框和配置卡片的关系;界面可能因版本而异。来源:官方快速入门。
+ +如果保存了订阅却没有节点,先检查卡片是否已启用,再检查地址是否返回 Clash 配置。文章网页、v2ray 订阅和 sing-box 配置不能仅通过改文件后缀变成 Clash 配置。 + +

03 选规则模式和一个手动节点

+ +在代理页使用 **规则模式**,找到处理普通代理流量的代理组,手动选一条节点。组名来自订阅,可能是“节点选择”“代理”或其他名称。 + +初次使用先手动选,方便知道当前线路是哪一条。若提供延迟测试,可以用它筛掉持续超时的节点,但仍要用实际访问验证。`DIRECT` 表示直连,选择它不会通过代理节点。 + +规则模式会依据配置决定哪些连接走节点、哪些直连;全局模式则使用全局策略组。切换全局并不能自动接管所有应用,它与下一步的系统代理解决的是不同问题。 + +

04 开启系统代理

+ +在客户端设置中找到 **系统代理** 并开启。若 macOS 为修改网络设置弹出授权提示,确认是本次客户端操作后按系统要求处理。首次连接可先保持 TUN 关闭。 + +
系统代理能处理哪些连接?
遵循系统代理的应用将请求交给本机代理端口
→
Clash Verge Rev按规则选择直连或节点
→
目标网站实际访问确认结果
未使用系统代理的应用,需要检查自身代理设置;有进一步接管需求时,再了解 TUN。
图 3 · 规则决定“交进来的连接怎么走”,系统代理决定哪些应用会把连接交进来。
+ +如果电脑上还有其他代理客户端,先关闭它们的系统代理和 TUN,避免多个程序反复修改同一套网络设置。 + +

05 通过网页和连接记录确认

+ +保持软件运行,重新打开一个希望通过节点访问的网站,再尝试实际需要的服务。可以同时查看客户端“连接”页面,找到刚才请求的域名,观察匹配规则和出口。 + +浏览器已能正常使用、某个应用仍不能连接时,先检查该应用是否遵循系统代理。不要一看到单个应用失败就认定整份订阅无效。 + +需要进一步了解 DNS 查询路径时,可以继续阅读 [DNS 防泄漏配置与验证](/a/mihomo-dns-leak.html)。其中的配置片段需要按当前客户端与平台调整,不是完成首次连接的必选步骤。 + +

06 更新、暂停和退出

+ +| 想做的事 | 操作 | +|---|---| +| 换一条线路 | 在当前代理组中选其他节点,再重新发起访问 | +| 更新节点列表 | 刷新订阅;若旧批次已失效,回本站查看较新的订阅地址 | +| 暂停代理 | 关闭系统代理;如果另行启用了TUN,也关闭它 | +| 完全退出 | 通过菜单栏图标的退出选项结束程序 | + +Mac 窗口左上角的红色关闭按钮可能只关闭窗口,后台进程仍在。判断是否断开时看代理开关和运行状态,不只看窗口是否消失。 + +

07 常见问题

+ +**系统代理开关开了,浏览器仍不通。** 先确认当前订阅和组内节点,再检查 macOS 当前网络服务的代理设置是否确实发生变化。权限提示未完成、其他客户端覆盖设置,都可能影响结果。 + +**找不到窗口。** 先从菜单栏图标恢复主窗口;如果之前使用过外接显示器,窗口可能保留了旧位置,可参考[官方 macOS FAQ](https://www.clashverge.dev/faq/macos.html)调整显示器布局后再打开。 + +**退出以后普通网页也打不开。** 到“系统设置 → 网络”中打开当前 Wi-Fi 或以太网的详情,检查“代理”是否残留指向本机已停止端口的手动设置。确认属于该客户端后再清理;如果使用过TUN,也先确认已关闭。 + +**一定要开 TUN 吗?** 浏览器通过系统代理能满足当前需求时,可以先这样使用。有应用接管需求再配置TUN,并留意它在macOS上可能调整系统DNS;不要把开关名称当成已经完成DNS泄漏验证。 + +
参考资料:安装文档、订阅说明。
diff --git a/docs/content/tutorials/windows.html b/docs/content/tutorials/windows.html new file mode 100644 index 00000000..86420760 --- /dev/null +++ b/docs/content/tutorials/windows.html @@ -0,0 +1 @@ +

本站分享的免费节点,可以通过订阅导入 Clash Verge Rev 使用。软件负责读取节点、选择线路和转发连接;安装好软件后,再把订阅加进去,就能开始配置。

这篇教程以 Windows 为例,从下载安装到导入本站的 Clash 订阅,再完成节点选择和连接验证。

先看完整流程
安装软件从官方发行页下载
→
导入订阅取得节点与规则
→
选择节点先用规则模式
→
开启代理打开网页验证

01 下载并安装 Clash Verge Rev

进入 Clash Verge Rev 官方发行页,找到 Windows 安装包,根据电脑架构选择版本。

电脑类型应选版本
常见 Intel / AMD 处理器的 Windows 电脑x64
Windows on ARM 设备ARM64
不确定自己是哪一种打开 Windows“设置 → 系统 → 系统信息”,查看系统类型

下载后运行安装程序,按提示完成安装并打开软件。本文适用于 Windows 10 / 11;其他系统的安装要求见官方安装文档。

如果安装完成却打不开主窗口,可能缺少 WebView2 运行环境。可按官方文档补装,或选择官方发行页提供的内置 WebView2 版本。

02 导入订阅,让软件显示节点

先打开本站的免费节点页面,进入较新的一篇分享,找到标明 Clash / Mihomo 格式的订阅。复制的是订阅地址,不是当前文章的网页地址;客户端会通过它取得节点配置。

  1. 在免费节点文章中复制 Clash / Mihomo 订阅链接。
  2. 回到 Clash Verge Rev,进入“订阅”页面。
  3. 把链接粘贴进订阅地址输入框,点击“导入”。
  4. 等待订阅卡片出现,再选择这张卡片作为当前配置。
  5. 进入“代理”页面,确认已经出现节点或代理组。
Clash Verge Rev 官方示例:进入订阅页,粘贴订阅链接,然后导入
图 1 · 在订阅页面粘贴链接并导入。图片来自官方快速入门文档,窗口样式可能与当前版本不同;点击可查看大图。

如果你拿到的是 YAML 配置文件,可以使用本地配置导入功能,具体入口见官方订阅管理说明。

03 选择规则模式和一个可用节点

在“代理”页面,先将模式设为 规则。然后找到负责普通代理流量的代理组,选择一个节点。不同订阅的组名不一样,可能叫“节点选择”“代理”或其他名称。

代理组相当于一组选项:可以手动选择某个节点,也可能提供自动选择。第一次使用时,先手动选一个容易辨认的节点,便于确认当前使用的是谁。

如果客户端提供延迟测试,可以先运行一次。显示延迟数值通常说明对测试地址可达;持续显示超时的节点可以先换一个。延迟越低不代表所有网站都越快,最后仍要打开实际网页确认。

选项含义入门时怎么选
规则按订阅中的规则决定直连还是代理日常使用先选它
全局进入内核的普通业务连接使用全局策略组遇到分流问题时再用于排查
直连 / DIRECT直接连接目标,不通过代理节点想使用节点时不要误选

“规则模式”采用的是当前订阅的规则,具体哪些网站走代理,要以这份配置为准。

04 开启系统代理

节点选好后,进入设置,找到 系统代理 并开启。它会让遵循系统代理设置的应用把请求交给 Clash Verge Rev。浏览器通常可以先用这种方式连接。

官方设置页面示例,箭头指出系统代理开关的位置
图 2 · 开启系统代理。图片来自官方快速入门文档;请按选项名称寻找,具体布局可能不同。

第一次使用,先把 规则模式 + 系统代理 这条流程走通。此时可以暂时保持 TUN 关闭,也不需要修改 DNS 或编写分流规则。

部分应用不遵循系统代理。如果浏览器已经正常、某个应用仍然无法连接,再检查该应用的代理设置,或了解客户端的 TUN 功能。切换到“全局”不会自动让这类应用进入代理。

05 打开网页,确认能够使用

保持客户端运行,打开一个你希望通过代理访问的网站。如果页面正常加载,再试一下你实际需要使用的服务。

想进一步确认,可以在客户端的“连接”页面找到刚才访问的域名,查看它匹配的规则和实际出口。有些网站按规则直连是正常现象,判断时应当看这次请求是否符合预期。

如果页面打不开,先按顺序检查三件事:订阅是否启用、代理组是否选中可用节点、系统代理是否开启。 都确认后,再换一个节点重试。

06 平时怎样切换、更新和关闭

想做的事操作方法
更换节点到“代理”页面,切换当前使用的代理组中的节点,然后重新发起请求
更新节点列表先在“订阅”页面刷新;若仍无可用节点,再查看本站较新的分享是否提供了新的订阅地址
暂停使用关闭系统代理;如果另外开启过 TUN,也一并关闭
完全退出使用托盘菜单中的退出选项;关闭主窗口可能只是隐藏到托盘
开机后自动运行确认日常使用正常后,再按需要开启开机启动;启动程序和启用代理是两件事

切换节点后,已有长连接可能仍沿用原连接。验证新节点时,重新打开页面或重连应用,比只看已经打开的页面更准确。

07 几个常见问题

导入成功,为什么还是没有节点? 先确认这份订阅已被选为当前配置。如果启用后仍为空,再核对订阅是否有效、格式是否适用于 Clash / Mihomo。

节点显示超时怎么办? 先确认电脑本身能正常上网,再尝试其他节点。免费节点的可用性会变化,如果这一批都无法连接,可以回到本站的免费节点页面,查看较新的分享,重新导入可用的 Clash 订阅。

退出软件后反而无法上网怎么办? 检查 Windows“设置 → 网络和 Internet → 代理”,是否仍保留指向本机已停止端口的手动代理。确认是该客户端留下的设置后再关闭;受单位管理的代理按其管理要求处理。

需要一开始就开 TUN 吗? 不需要。先用系统代理完成浏览器连接;确有应用不能被接管时,再阅读系统代理与 TUN 的区别及选择方法。安装、窗口显示等问题可查官方 Windows FAQ。

完成入门后的下一步

能稳定连接后,可以继续阅读DNS 防泄漏配置与验证,了解域名查询由谁处理、从哪里发出。

diff --git a/docs/content/tutorials/windows.md b/docs/content/tutorials/windows.md new file mode 100644 index 00000000..612e066e --- /dev/null +++ b/docs/content/tutorials/windows.md @@ -0,0 +1,93 @@ +本站分享的免费节点,可以通过订阅导入 Clash Verge Rev 使用。软件负责读取节点、选择线路和转发连接;安装好软件后,再把订阅加进去,就能开始配置。 + +这篇教程以 Windows 为例,从下载安装到导入本站的 Clash 订阅,再完成节点选择和连接验证。 + +
先看完整流程
安装软件从官方发行页下载
→
导入订阅取得节点与规则
→
选择节点先用规则模式
→
开启代理打开网页验证
+ + + +

01 下载并安装 Clash Verge Rev

+ +进入 [Clash Verge Rev 官方发行页](https://github.com/clash-verge-rev/clash-verge-rev/releases/latest),找到 Windows 安装包,根据电脑架构选择版本。 + +| 电脑类型 | 应选版本 | +|---|---| +| 常见 Intel / AMD 处理器的 Windows 电脑 | x64 | +| Windows on ARM 设备 | ARM64 | +| 不确定自己是哪一种 | 打开 Windows“设置 → 系统 → 系统信息”,查看系统类型 | + +下载后运行安装程序,按提示完成安装并打开软件。本文适用于 Windows 10 / 11;其他系统的安装要求见[官方安装文档](https://www.clashverge.dev/install.html)。 + +如果安装完成却打不开主窗口,可能缺少 WebView2 运行环境。可按官方文档补装,或选择官方发行页提供的内置 WebView2 版本。 + +

02 导入订阅,让软件显示节点

+ +先打开本站的[免费节点页面](/freenode),进入较新的一篇分享,找到标明 **Clash / Mihomo** 格式的订阅。复制的是订阅地址,不是当前文章的网页地址;客户端会通过它取得节点配置。 + +1. 在免费节点文章中复制 **Clash / Mihomo** 订阅链接。 +2. 回到 Clash Verge Rev,进入“订阅”页面。 +3. 把链接粘贴进订阅地址输入框,点击“导入”。 +4. 等待订阅卡片出现,再选择这张卡片作为当前配置。 +5. 进入“代理”页面,确认已经出现节点或代理组。 + +
Clash Verge Rev 官方示例:进入订阅页,粘贴订阅链接,然后导入
图 1 · 在订阅页面粘贴链接并导入。图片来自官方快速入门文档,窗口样式可能与当前版本不同;点击可查看大图。
+ +如果你拿到的是 YAML 配置文件,可以使用本地配置导入功能,具体入口见[官方订阅管理说明](https://www.clashverge.dev/guide/profile.html)。 + +

03 选择规则模式和一个可用节点

+ +在“代理”页面,先将模式设为 **规则**。然后找到负责普通代理流量的代理组,选择一个节点。不同订阅的组名不一样,可能叫“节点选择”“代理”或其他名称。 + +代理组相当于一组选项:可以手动选择某个节点,也可能提供自动选择。第一次使用时,先手动选一个容易辨认的节点,便于确认当前使用的是谁。 + +如果客户端提供延迟测试,可以先运行一次。显示延迟数值通常说明对测试地址可达;持续显示超时的节点可以先换一个。**延迟越低不代表所有网站都越快**,最后仍要打开实际网页确认。 + +| 选项 | 含义 | 入门时怎么选 | +|---|---|---| +| 规则 | 按订阅中的规则决定直连还是代理 | 日常使用先选它 | +| 全局 | 进入内核的普通业务连接使用全局策略组 | 遇到分流问题时再用于排查 | +| 直连 / DIRECT | 直接连接目标,不通过代理节点 | 想使用节点时不要误选 | + +“规则模式”采用的是当前订阅的规则,具体哪些网站走代理,要以这份配置为准。 + +

04 开启系统代理

+ +节点选好后,进入设置,找到 **系统代理** 并开启。它会让遵循系统代理设置的应用把请求交给 Clash Verge Rev。浏览器通常可以先用这种方式连接。 + +
官方设置页面示例,箭头指出系统代理开关的位置
图 2 · 开启系统代理。图片来自官方快速入门文档;请按选项名称寻找,具体布局可能不同。
+ +第一次使用,先把 **规则模式 + 系统代理** 这条流程走通。此时可以暂时保持 TUN 关闭,也不需要修改 DNS 或编写分流规则。 + +部分应用不遵循系统代理。如果浏览器已经正常、某个应用仍然无法连接,再检查该应用的代理设置,或了解客户端的 TUN 功能。切换到“全局”不会自动让这类应用进入代理。 + +

05 打开网页,确认能够使用

+ +保持客户端运行,打开一个你希望通过代理访问的网站。如果页面正常加载,再试一下你实际需要使用的服务。 + +想进一步确认,可以在客户端的“连接”页面找到刚才访问的域名,查看它匹配的规则和实际出口。有些网站按规则直连是正常现象,判断时应当看这次请求是否符合预期。 + +如果页面打不开,先按顺序检查三件事:**订阅是否启用、代理组是否选中可用节点、系统代理是否开启。** 都确认后,再换一个节点重试。 + +

06 平时怎样切换、更新和关闭

+ +| 想做的事 | 操作方法 | +|---|---| +| 更换节点 | 到“代理”页面,切换当前使用的代理组中的节点,然后重新发起请求 | +| 更新节点列表 | 先在“订阅”页面刷新;若仍无可用节点,再查看本站较新的分享是否提供了新的订阅地址 | +| 暂停使用 | 关闭系统代理;如果另外开启过 TUN,也一并关闭 | +| 完全退出 | 使用托盘菜单中的退出选项;关闭主窗口可能只是隐藏到托盘 | +| 开机后自动运行 | 确认日常使用正常后,再按需要开启开机启动;启动程序和启用代理是两件事 | + +切换节点后,已有长连接可能仍沿用原连接。验证新节点时,重新打开页面或重连应用,比只看已经打开的页面更准确。 + +

07 几个常见问题

+ +**导入成功,为什么还是没有节点?** 先确认这份订阅已被选为当前配置。如果启用后仍为空,再核对订阅是否有效、格式是否适用于 Clash / Mihomo。 + +**节点显示超时怎么办?** 先确认电脑本身能正常上网,再尝试其他节点。免费节点的可用性会变化,如果这一批都无法连接,可以回到本站的[免费节点页面](/freenode),查看较新的分享,重新导入可用的 Clash 订阅。 + +**退出软件后反而无法上网怎么办?** 检查 Windows“设置 → 网络和 Internet → 代理”,是否仍保留指向本机已停止端口的手动代理。确认是该客户端留下的设置后再关闭;受单位管理的代理按其管理要求处理。 + +**需要一开始就开 TUN 吗?** 不需要。先用系统代理完成浏览器连接;确有应用不能被接管时,再阅读[系统代理与 TUN 的区别及选择方法](/a/system-proxy-vs-tun.html#choose)。安装、窗口显示等问题可查[官方 Windows FAQ](https://www.clashverge.dev/faq/windows.html)。 + +
完成入门后的下一步

能稳定连接后,可以继续阅读DNS 防泄漏配置与验证,了解域名查询由谁处理、从哪里发出。

diff --git a/docs/maintenance/EDITORIAL_API.md b/docs/maintenance/EDITORIAL_API.md new file mode 100644 index 00000000..6d296c2c --- /dev/null +++ b/docs/maintenance/EDITORIAL_API.md @@ -0,0 +1,161 @@ +# FNA_V3 独立文章 API + +状态:2026-10-27本地实施并联调;2026-10-29已随独立test预览提交、推送和部署,10篇教程真实API迁移通过后,test编辑接口已关闭且临时密钥移除。正式站现已切换,正式10篇教程亦通过同一API迁移;生产临时密钥用后删除,编辑接口默认关闭,后续明确写作/发布任务再按绑定环境启用并完成后关闭。test执行和回执沿[发布记录](RELEASE_PREFLIGHT_2026-10-28.md#当前门槛先test预览确认后再切正式2026-10-29),日常本地调用不受影响。用户明确采用本站独立接收 API,不经过 ATOM;不新增 ATOM 依赖。入口为 `http://fna-v3.loc/api/editorial/v1`,生产地址尚未指定。 + +## 职责与数据 + +AI负责选题、正文、图解、官方资料核对与自然内链;本站负责保存草稿、生成实际模板预览、按冻结版本发布、记录结果和回退。文章目录和关联登记仍以[写作索引](../content/WRITING.md)为准;API不自动改写该Markdown,也不自动创造反向链接。将相关旧文的修改显式放进同一批次,预览后原子发布。 + +项目正文源保留可编辑稿;`editorial_drafts`保存收到并渲染后的冻结版本,发布读取该快照,不临时重新读取文件。`articles`为公开显示数据,草稿不写入它。`editorial_documents`按稳定`content_key`绑定本站文章;`editorial_versions`保留已发布版本和首次接管旧文的基线版本0;`editorial_publications`保存独立发布回执及后续处理状态。图片元信息在`editorial_assets`。 + +新API不调用旧接收器,不发送旧Telegram通知、IndexNow提交或ATOM请求。旧资源接收接口继续沿用原流程,不在本次改造范围;普通编辑API拒绝免费节点与小火箭ID两个自动资源栏目。旧接口/人工直接编辑同一文章会造成草稿基线变化,新API发布时返回409,不能静默覆盖并行修改。 + +## 凭据与环境 + +配置:`config/editorial.php`。 + +- 本地默认启用,但必须先有有效凭据。生产默认关闭,需部署时明确设置`EDITORIAL_API_ENABLED`、`EDITORIAL_BASE_URL`和独立搜索索引;本次没有生产凭据或上线操作。 +- 本地安装命令`php artisan editorial:setup`仅允许本机`fna_v3`,已存在凭据不覆盖。凭据在`storage/app/private/editorial/credential.json`(目录700、文件600,Git忽略),结构使用`gemdocs.credential.v1`及`fields.api_key`,绑定项目、环境和base_url。程序在内存中读取,禁止打印、复制进正文、提交Git或放到命令参数。 +- 认证为`Authorization: Bearer <专用密钥>`。应用提供下述CLI代为读取和发送,不需要AI将密钥带入工具输出。 +- 所有编辑接口拒绝整页缓存;预览和私有图片使用30分钟签名地址,返回`noindex, nofollow`、`private, no-store`。持有签名链接的人在有效期内可预览,链接不应公开转载;失效后通过查询草稿重新取得链接。 +- 发布接口按分钟限流;API错误不输出SQL、凭据或请求头。生产认证、HTTPS与访问路线仍按项目部署约束核实,不能因代码已存在就认为生产已可调用。 + +## 调用方式 + +以下命令调用当前环境绑定的API,`path`相对于`/api/editorial/v1/`,输出JSON结构为`http_status`与`data`。 + +```sh +php artisan editorial:request GET catalog +php artisan editorial:request GET source-articles/362 +php artisan editorial:request POST assets --image=/绝对路径/操作图.png +php artisan editorial:request POST drafts --payload=/绝对路径/draft.json +php artisan editorial:request GET drafts/草稿UUID +php artisan editorial:request POST drafts/草稿UUID/publish --payload=/绝对路径/publish.json +php artisan editorial:request GET publications/发布请求UUID +``` + +示例中的中文路径和UUID均需替换。请求正文放文件,不把多行正文或密钥拼接进shell。CLI关闭HTTP代理和重定向,本地模式拒绝非本地目标;外部环境的调用仍需既有访问授权。 + +### 1 保存草稿 + +`POST /drafts`: + +```json +{ + "request_id": "29e2f78a-7adc-4bf6-9eef-1c5f4a586b13", + "articles": [ + { + "content_key": "verge-windows-start", + "expected_revision": 0, + "adopt_article_id": 362, + "slug": "clash-verge-rev-windows", + "title": "Clash Verge Rev 使用教程:从安装到第一次连接(Windows)", + "summary": "下载安装、导入订阅、选择节点和开启系统代理。", + "category_slug": "windows", + "format": "markdown", + "body": "

下载与安装

\n\n此处为实际正文。", + "cover": null, + "show_cover": false + } + ] +} +``` + +这是结构示例,不可拿占位正文覆盖现有教程。完整正文应来自项目源文件或已核对的接收端原文。 + +- `request_id`为本次保存动作的新UUID;同UUID同正文重试返回同草稿,不递增版本;同UUID改正文返回409。每批最多10篇,单篇正文最多500000字符。 +- `content_key`为写作索引中的稳定键。首次为0,后续`expected_revision`必须等于`GET /articles/{key}`返回的`latest_revision`,成功后递增。新草稿会使同文章的旧草稿失去发布资格,但不会改变线上已有正文。 +- 新文章省略`adopt_article_id`。接管现有文章必须显式指定准确ID并沿用原slug;不因标题相似自动绑定。首次接管仅建立映射和旧版快照,不改公开正文。不能把已有键转绑另一篇文章,也不能改已绑定文章URL。 +- `category_slug`必须为本站已启用的编辑栏目。`tag_ids`可选,必须是已有标签ID;省略时保留旧文标签,新文默认为空,不自动创建标签。 +- `format`为`markdown`(默认)或`html`。Markdown支持基础HTML图解,但过滤危险链接、脚本等;富文本不接受任意脚本、事件属性或内联样式。段落锚点使用显式`id`。 +- `cover`支持已存在的本站`/images/...`路径,或上传后的`asset:SHA256`;显式null可清除旧封面,省略时保留。`show_cover`控制正文头图,省略时保留旧值,新文默认不展示头图。 +- 站内文章链接为`/a/slug.html#anchor`。本站完整域名链接不作为站内链接接受;引用公共官方资料可用外部HTTPS链接。文章目标必须已发布或在同批草稿内,锚点必须存在。分类链接校验真实父子关系,避免宽松路由把错误URL也返回200。 + +返回`draft_id`、`hash`、`status`及每篇文章的版本、预期路径和`preview_url`。查询草稿会生成新的短期预览链接;草稿内容不变。预览复用本站文章模板,关闭统计、点赞和热门列表;同批次文章之间的链接改为签名预览,避免跳到不存在的正式页。 + +### 新文章点赞设置 + +2026-10-29起,创建新文时支持可选`like_settings`,例如: + +```json +"like_settings": {"seven_day": 12, "yearly": 50, "one_year": 200} +``` + +省略时采用[AI写作规范的默认参数](../content/WRITING.md#ai-新文章的点赞参数2026-10-29),在草稿保存时随机取值并冻结;草稿响应`articles[].like_settings`返回确认值。旧文改稿、接管及内容回退保留原点赞参数/进度,普通改稿显式传入此对象返回422;0可在新建时关闭对应项。旧冻结草稿不追加新默认值。 + +发布后鉴权`GET source-articles/{id}`的`like_growth`可核对剩余额度、持续年度参数及一次性年度目标、已支付量和开始时间。年度额度按发布时间计时,累计增加该额度后停止,与真实点赞和持续年度随机增长独立。迁移、调度、字段范围与回退见[文章自动点赞维护](ARTICLE_LIKES.md);先执行指定新增迁移,再使用新代码。 + +### 2 图片 + +`POST /assets`使用multipart的`image`字段。支持PNG/JPEG/WebP/GIF,最多8MB,并限制宽高和像素数;不接收SVG/HTML上传,不主动抓取远端图片URL。返回SHA256、尺寸和`asset:SHA256`引用: + +```markdown +![导入订阅操作图](asset:实际返回的64位SHA256) +``` + +原图先在私有存储,不生成公开地址。签名预览通过临时图片路由读取;正式发布时校验哈希并生成本站`/images/editorial/SHA256.ext`地址,正文替换为此路径。上传文件无同名覆盖问题;失败批次可能留下已准备但未引用的内容寻址图片,不自动删除可能仍被其他版本使用的素材。 + +### 3 发布确认过的版本 + +`POST /drafts/{draft_id}/publish`: + +```json +{ + "request_id": "0cf94c73-bafb-4a6c-9cef-39d72e5bc24e", + "expected_hash": "替换成保存草稿返回的64位hash" +} +``` + +发布UUID与草稿UUID分开。确认所看版本后使用它的hash;不要重建另一份正文来发布。发布前再次检查最新版本、现有文章基线、栏目/标签、图片、目标链接及受影响旧文的入向锚点。批次中任一篇冲突或失效,整批文章与版本/回执事务回滚。 + +成功后按稳定映射创建/更新文章,保留已有URL、创建时间、计数、置顶和身份。批次里的所有正文修改同时提交;冻结发布回执与内容写入在同一数据库事务中。重复提交同一发布UUID返回原回执;同UUID换目标/版本返回409。同一草稿换一个发布UUID重试也只返回已有回执,不重复创建文章。 + +响应包含: + +- `status: published`:本次内容已写入本站公开文章表;这是所调用环境的状态,本地成功不代表生产成功。 +- `articles`:各文章的`content_key`、`article_id`、`revision`和URL。 +- `effects.cache/search/sitemap`:各后续处理的独立结果。搜索暂时失败不撤销已提交正文,返回`pending`,不能重发正文来弥补搜索失败。 + +后续处理为刷新本站响应缓存与热门数据缓存、同步本站搜索,以及使用数据库驱动的sitemap。缓存未刷新时sitemap也标记pending。不调用搜索引擎主动提交。 + +### 4 查询、重试与回退 + +| 方法与路径 | 作用 | +| --- | --- | +| `GET /catalog` | 当前可用编辑栏目与文章元信息,含已接管键和版本 | +| `GET /source-articles/{id}` | 接管旧文前读取实际HTML、封面、标签、栏目与管理状态 | +| `GET /articles/{key}` | 最新草稿版本、已发布版本、稳定ID/路径、已发布历史列表 | +| `GET /articles/{key}/versions/{revision}` | 读取某个已发布版本的冻结内容;旧文接管基线为0 | +| `GET /drafts/{id}` | 查询保存结果,刷新预览地址 | +| `GET /publications/{id}` | 查询发布UUID的原回执和当前后续处理状态 | +| `POST /publications/{id}/synchronize` | 只重试未完成的缓存/搜索处理,不重写文章;搜索读取当前公开版本,避免旧重试覆盖新索引 | +| `POST /articles/{key}/rollback` | 从指定历史版本建立新草稿,供预览后另行发布 | + +回退请求同样包含新`request_id`,并给出当前`expected_revision`和历史`target_revision`。它不会马上覆盖当前文章;返回新草稿后,沿同一预览/发布步骤恢复,版本继续递增、URL不变。若旧版锚点不能满足现有入向链接,需要将关联文的修正一起组批,不能强制制造断链。 + +HTTP401认证失败,403签名无效/过期,404对象不存在,409幂等/版本/所有权冲突,422格式或链接不满足条件,503功能关闭或凭据绑定无效。网络结果未知时,先按原UUID查询,不盲目生成新UUID重发。 + +## 搜索隔离 + +`Articles::searchableAs()`优先使用`editorial.search_index`。本地为独立`fna_v3_articles`,已把169篇现有公开文章初始化到新索引,未改原继承的`articles`索引。正常站内搜索和新API写入使用同一索引。`editorial:reindex`用于初始化/补全;后续每次发布只更新本批当前文章。 + +本地仅允许回环Meilisearch和`fna_v3_`前缀。生产必须明确专属索引及服务地址,不能沿用未知共享索引。集合/数据库搜索直接读取当前文章;未支持或未配置的驱动返回pending。Meilisearch任务等待成功后才报告done。 + +## 安装、验收与恢复 + +追加迁移:`database/migrations/2026_10_27_190000_create_editorial_tables.php`。执行时只指定此迁移,不使用`migrate:fresh`或批量重置现有数据库。后续代码部署遵守Git发布流程;本次本地安装不授权生产部署。 + +```sh +php artisan migrate --path=database/migrations/2026_10_27_190000_create_editorial_tables.php --force +php artisan editorial:setup +php artisan editorial:reindex +``` + +本地已完成: + +- SQLite内存隔离功能测试:认证/环境绑定、缓存隔离、草稿私有、签名到期、幂等、版本冲突、原子发布、显式接管、并行修改保护、入向锚点、图片和代码换行、回退与搜索重试;结果见`output/editorial-api/tests.xml`。 +- 真实本地HTTP:无认证401、图片上传与草稿预览、两文章互链整批发布、同UUID重试、新版、回退、正式HTTP200、真实站内搜索和sitemap;见`output/editorial-api/http-verification.json`。 +- 1360/390预览截图:签名图片、同批跳转、无点赞、noindex、无横向溢出;浏览器只允许本地来源,未发线上请求。见`output/editorial-api/browser-verification.json`和同目录PNG。 +- 临时文章2篇及本次测试版本/回执/图片已清理,原169篇文章完整行哈希一致。安装验收结束时接收表为空,后续正常稿件会保留版本和回执;凭据留在私有存储。 + +恢复时先关闭`EDITORIAL_API_ENABLED`,保留5张接收表、版本和回执及图片。已发布正文仍在`articles`可正常显示;撤销某次文章更新优先走历史版本回退。代码回退不得顺带drop表或清理可能被正式文章引用的图片。若撤回本地搜索切换,应在核对原索引后调整`EDITORIAL_SEARCH_INDEX`与模型配置,不删除未知共享索引。 diff --git a/docs/maintenance/ILLUSTRATIONS.md b/docs/maintenance/ILLUSTRATIONS.md new file mode 100644 index 00000000..ae4be033 --- /dev/null +++ b/docs/maintenance/ILLUSTRATIONS.md @@ -0,0 +1,65 @@ +# 本地插画资源与配图 + +2026-10-27修正此前错误的本地配图实现。当前状态(2026-10-29):本地、独立test与正式cfn均已接入;正式资源为https://resource-v2.gemcook.net,22猫/15狗,84/90篇固定分配与test逐项一致。正式消费者仅fna-v3项目read/write,test仍独立只读。部署、备份、权限与323项服务器验收统一见[正式切换](RELEASE_PREFLIGHT_2026-10-28.md#正式切换2026-10-29)。下文“仅本地/正式未切换”为此前历史状态。 + +素材及图池事实由 [Resource V2 插画集合说明](/Users/hellcat/Documents/GemCodes/resource.loc/v2/docs/CFN_ILLUSTRATIONS.md) 维护,本页维护FNA_V3消费方式。仅本地,未提交、推送或部署。此前“只用12张猫图替换显示”没有完成原图池扩充;旧哈希算法也没有避免连续重复,相关旧验收不足以证明需求已完成。 + +## 当前规则 + +免费节点当前22张猫图(含乔治此前2张猫图,已排除毛线球旧试画);免费苹果ID(原免费小火箭ID,分类9、shadowrocketids)当前15张狗图。2026-10-28本批追加12张狗图,猫图去重保留。图池与每篇文章的固定分配都保存在本地Resource V2的项目引用中。首次按文章创建时间从旧到新通过HTTP批量分配;每次依次轮换一张图,一轮用完后再循环。重复发送同一文章键复用原图,不推进游标;之后扩充图池也不重新洗牌已有文章。 + +`config/illustrations.php`只维护分类1→freenode、分类9→shadowrocketids,以及V2基址和私有凭据文件路径,不保存图片URL清单。`app/Services/IllustrationPool.php`通过鉴权HTTP接口读取图池与分配;`app/Models/Articles.php`的sThumb读取器统一用于列表、侧栏、详情和OG。快照在file cache缓存60秒,最近成功快照另保留供短暂故障使用。没有成功快照时回退原字段;故障期间不创建新配图,不自动调用旧线上接口。 + +`ArticlesController`的免费节点、免费苹果ID接收方法,以及通用receive针对这两个分类,均在启用本地V2时走同一分配接口。调用失败中止配图阶段,不伪造成功。其他分类不变;非local或关闭开关时保留既有逻辑,未迁移生产调用方。 + +## 接口与凭据 + +环境绑定已扩展:local只接受`http://resource.loc:8612`,staging只接受`https://test.clashfreenode.com/resource-v2`,production只接受`https://resource-v2.gemcook.net`;均需显式启用且凭据project/base_url匹配。正式cfn已切换,其他同代码实例尚未自动迁移。开关RESOURCE_V2_ILLUSTRATIONS_ENABLED兼容旧LOCAL_ILLUSTRATIONS_ENABLED。FNA_V3专用客户端项目为fna-v3,作用域read/write;私有JSON由RESOURCE_V2_CREDENTIAL_FILE指定,位于resource/v2/.local/clients,不进入浏览器或Git。新图片导入用一次性所有者凭据,完成后已撤销。真实接口: + +- GET `/api/v2/pools/{pool}`:取回有序成员和已分配文章。 +- POST `/api/v2/pools/{pool}/selections`:JSON keys数组,首次分配/重复交付均幂等。 +- 图片浏览器仍读取V2返回的 `/media/{publication}`,不带Bearer。 + +API契约、上限、项目隔离和图池维护见[Resource V2 API](/Users/hellcat/Documents/GemCodes/resource.loc/v2/docs/API.md)。新增素材先在V2上传、发布、授权消费者,再用pool引用扩充成员,不在FNA_V3写死图片地址。原160篇文章数据库sThumb未改写;本地原稿与生产旧文件均保留。未来上线另核对生产素材和服务配置,不能直接发布本地URL。 + +## 本地运行 + +固定入口 `http://fna-v3.loc/`;栏目为 `/freenode` 与 `/shadowrocketids`。本机 hosts 指向127.0.0.1,前端 Nginx 配置 `/usr/local/etc/nginx/servers/fna-v3.loc.conf` 仅监听回环80端口;转发至 GemCodesAccess 后端18882,PHP FPM9000,根目录为本项目 public。后端虚拟主机位于 GemCodesAccess 的 `service.conf`,由 `BEGIN/END FNA_V3 local virtual host` 标记界定。 + +Resource V2 开发服务监听127.0.0.1:8612。FNA_V3 使用 Vite dev,当前内部端口5187,启动命令 `npm run dev -- --port 5187 --host 127.0.0.1 --strictPort`;未执行发布构建。应用URL为固定域名,内部端口不替代日常入口。服务重启后按各项目运维说明恢复开发进程。 + +## 2026-10-27 旧版细节补齐 + +V2现会跳过缺失/损坏/符号链接/未发布等不可用候选;同一文章原图因物理故障不可用时,GET以unavailable标记,FNA_V3调用分配接口修复并保持其他文章分配不动。全池坏时该图留空,不用数据库旧URL伪装恢复。明确撤回发布/权限或资产停用则停止展示,不自动替换或重新公开。图池读取支持next游标,消费者读完所有页,60秒缓存/最近成功快照保留。 + +调用方本轮故障测试使用独立内存cache与fake HTTP,不污染真实缓存或文章;服务端真实HTTP测试使用一次性隔离实例,未触碰本地猫狗素材。完整接口和旧版对应关系以[Resource V2核对正文](/Users/hellcat/Documents/GemCodes/resource.loc/v2/docs/LEGACY_PARITY.md)为准。本地21猫/3狗、160篇文章配图保留,未上线。 + +## 验收与回退 + +2026-10-28用户明确不要早期试画 `freenode-cat-yarn-20261023`(粉底薄荷绿小猫玩毛线球)。通过本地V2 API移除消费者fna-v3的`pool:freenode:009`,并为fn20260808、fn20260903、fn20260925、fn20261016四篇替换固定配图,避开各自相邻文章;其他固定分配逐项对照未变。图池现场原有23项(含后续新增图),移除后22项。已刷新配图快照和页面缓存;源文件、私有归档与其他使用方未删除,生产未改。该图片不再纳入本地FNA_V3图池;不要根据历史导入清单重新加回。可恢复回执:`/private/tmp/fna-remove-yarn-receipt.json`。 + +2026-10-27:真实鉴权HTTP导入9张旧猫图、授权及创建图池、为78篇免费节点和82篇免费小火箭ID建立固定分配。160篇按当前栏目排序逐条检查:21张猫图/3张狗图均被使用,相邻配图重复为0。数据库原配图字段、其他7篇文章均未改变;重复投递、关闭开关、production保护、服务503保留最近配图与拒绝新分配均通过。 + +Resource V2隔离测试19项/154断言通过,包含轮换、项目隔离、只读凭据拒绝写、非法键、已撤回图片和失败保护。两栏目、两篇详情在1280/390宽度下图片加载、无相邻重复、无横向溢出;测试只放行本地来源。没有执行包含通知/索引外发的完整文章接收请求,接收方法的配图路径用相同服务方法真实HTTP重试验证。 + +证据位于 `/Users/hellcat/Documents/Codex/2026-10-23/cfn/outputs/fna-v3-pool-fix-verification.json`、`fna-v3-fixed-page-verification.json` 和 `fna-v3-fixed-*.png`。旧版截图和报告只作历史,不作为修正后验收。 + +回退展示:本地.env设置LOCAL_ILLUSTRATIONS_ENABLED=false,执行本项目 `php artisan config:clear` 与 `php artisan responsecache:clear`。原字段重新显示,不恢复整库、不删除resource引用/图池/素材。仅回退页面不撤销已被其他方使用的发布。代码备份和9张旧图SSH来源清单在工作目录work/illustration-fix;域名回退只移除独立server块及hosts条目,不覆盖其他聊天配置。 + +## 2026-10-28 两张插画追加 + +用户指定「蓝椅上的橘白猫」「窗台与蓝花」加入免费节点。原PNG及完整提示词已并入Resource V2原集合清单,WebP88展示图经真实本地HTTP上传、发布、授权并追加两个pool引用。FNA_V3实际IllustrationPool回读23张且包含两张新图,原78篇免费节点文章及其他消费者引用、游标均逐项保持不变;扩池供后续新文章轮换使用,不重分配旧文章。栏目本地HTTP200;未做本轮浏览器页面验收,未提交、推送或部署。 + +证据:`/Users/hellcat/Documents/Codex/2026-10-28/new-chat/outputs/fna-v3-two-cats-integration-20261028.json`;素材、备份与撤销凭据见Resource V2集合说明。本次没有修改FNA_V3代码或文章数据库字段。 + +## 栏目显示名称(2026-10-28) + +用户要求将“免费小火箭ID”改为“免费苹果ID”。本地fna_v3.categories仅更新ID9的sName;sSlug仍为shadowrocketids,URL、文章归属、正文和狗图池不变。直接限定字段更新,未触发分类模型关联文章touch;清除global_nav_tree和页面响应缓存后,浏览器回读四个导航/栏目链接均为新名,列表卡片分类同步显示新名。原值备份 `codex/output/category-apple-id-rename-before-20261028.json`,截图 `codex/output/category-apple-id-rename-preview-20261028.png`。未发布生产;后续上线须将该栏目名作为定点数据变更处理,不以整库覆盖迁移。历史验收段中的旧名保留其原时点含义。 + +## 2026-10-28 本聊天剩余素材入池 + +用户指定猫→免费节点、狗→免费小火箭ID,并明确第一张截图排除整组三猫三狗,另三张截图分别排除早期光滑蓝椅猫、黄月黑猫、浅蓝背景坐猫;共9张排除,不导入且不删除原文件。剩余两张猫此前已入池,去重保留;新导入12张狗图(两组各5张,加闻雏菊史宾格、编号001叼拖鞋梗犬)。 + +Resource V2原图、完整提示词私有归档及WebP88公开展示/授权/池引用追加均通过真实本地HTTP完成。FNA_V3实际服务回读猫22/狗15,78+82篇原固定配图及游标逐项未变,新素材供后续文章轮换。先前明确移除的毛线球猫未恢复。两栏目本地HTTP200,未做本轮浏览器页面验收,未提交、推送或部署。 + +证据:`/Users/hellcat/Documents/Codex/2026-10-28/new-chat/outputs/fna-v3-remaining-art-integration-20261028.json`;每项排除hash、素材清单、备份与临时客户端撤销见资源集合正文及回执。本次未修改文章数据库字段或网站代码。 diff --git a/docs/maintenance/PREVIEW_VERIFICATION_2026-10-29.json b/docs/maintenance/PREVIEW_VERIFICATION_2026-10-29.json new file mode 100644 index 00000000..c23a6c1d --- /dev/null +++ b/docs/maintenance/PREVIEW_VERIFICATION_2026-10-29.json @@ -0,0 +1,1561 @@ +{ + "checks": [ + { + "check": "staging and independent DB", + "passed": true, + "detail": null + }, + { + "check": "no private production tables copied", + "passed": true, + "detail": null + }, + { + "check": "10 tutorials migrated through API", + "passed": true, + "detail": null + }, + { + "check": "editorial disabled and key removed", + "passed": true, + "detail": null + }, + { + "check": "home HTTP200", + "passed": true, + "detail": 200 + }, + { + "check": "home latest free-node article", + "passed": true, + "detail": "fn20261029" + }, + { + "check": "home no free-node menu highlight", + "passed": true, + "detail": null + }, + { + "check": "test robots header", + "passed": true, + "detail": null + }, + { + "check": "test robots meta", + "passed": true, + "detail": null + }, + { + "check": "no production analytics", + "passed": true, + "detail": null + }, + { + "check": "no new advertising code", + "passed": true, + "detail": null + }, + { + "check": "test canonical", + "passed": true, + "detail": null + }, + { + "check": "robots disallow whole test site", + "passed": true, + "detail": null + }, + { + "check": "HTTP redirects to HTTPS", + "passed": true, + "detail": 301 + }, + { + "check": "blocked legacy/private route /api/article/receive", + "passed": true, + "detail": 404 + }, + { + "check": "blocked legacy/private route /api/v1/telegram/hook", + "passed": true, + "detail": 404 + }, + { + "check": "blocked legacy/private route /test/hello", + "passed": true, + "detail": 404 + }, + { + "check": "blocked legacy/private route /.env", + "passed": true, + "detail": 403 + }, + { + "check": "closed editorial API", + "passed": true, + "detail": 503 + }, + { + "check": "page /freenode", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /freenode", + "passed": true, + "detail": null + }, + { + "check": "page /shadowrocketids", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "page /client", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /client", + "passed": true, + "detail": null + }, + { + "check": "page /advanced", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /advanced", + "passed": true, + "detail": null + }, + { + "check": "page /a/m169.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m174.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m173.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m167.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m172.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/mihomo-dns-leak.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m170.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/system-proxy-vs-tun.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m171.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/clash-verge-rev-windows.html", + "passed": true, + "detail": 200 + }, + { + "check": "noindex /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /", + "passed": true, + "detail": null + }, + { + "check": "no development asset /", + "passed": true, + "detail": null + }, + { + "check": "no development asset /", + "passed": true, + "detail": null + }, + { + "check": "no development asset /", + "passed": true, + "detail": null + }, + { + "check": "no development asset /", + "passed": true, + "detail": null + }, + { + "check": "no development asset /", + "passed": true, + "detail": null + }, + { + "check": "no development asset /", + "passed": true, + "detail": null + }, + { + "check": "no development asset /", + "passed": true, + "detail": null + }, + { + "check": "no development asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no development asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no development asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no development asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no development asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no development asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no development asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no development asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no development asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no development asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no development asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no development asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no development asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no development asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no development asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no development asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /client", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no development asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "asset /build/assets/app-BCx10ygF.css", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/app-Ba5joxXD.css", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/app-DDSp2ths.js", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-brands-400-BfBXV7Mm.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-regular-400-BVHPE7da.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-solid-900-8GirhLYJ.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-v4compatibility-DnhYSyY-.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/iconfont-B3tZHDj4.ttf", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/iconfont-D7mxe_Lh.woff", + "passed": true, + "detail": 200 + }, + { + "check": "asset /css/tutorials.css", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/clash-meta-android-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/dns-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/mac-client-guide-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/migration-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/quantumult-x-ios-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/system-proxy-tun-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/v2rayng-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/verge-import.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/verge-linux-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/verge-mac-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/verge-system-proxy.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/windows-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/136dd033-69bc-4a0f-9d5c-4e9bde1b4722", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/1cc79de9-790c-426b-92a8-61d4d348549b", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/24f44705-9b6b-4b79-bbcc-07d0a1e09993", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/3364360b-f867-428e-9284-713003d72623", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/37281c08-bc04-4bc5-a0fc-70419f8faff1", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/3b68b6cd-eb2c-4959-8b19-6f1f8bd87993", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/3f36c36d-2318-409f-9a03-c183c2e430f2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/52b01b49-274e-48c4-99f5-1391aaa75353", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/604e7b3f-a0ed-4305-b9aa-f8b862fb19c9", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/60f03c67-a343-4395-aa69-dd0c2e1885ec", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/6301fb77-cf09-4038-afbb-ebc50ad3d16e", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/6917791e-9f01-4493-b5b9-f1e55ebd859c", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/76ab0135-5c3f-4e27-8bae-87a94b3d55a2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/7fd23c13-426c-4d6c-aa2a-c164840125d3", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/816dcf82-7ba5-438a-b478-d360c898030b", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/8c4a15a6-46e7-48f0-b1ed-f19368c47d19", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/8e117bf6-c50f-4c94-84e7-59734908dc23", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/8ed764bb-712e-4006-a154-ca44a0e20b5a", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/aa2c5fb9-adee-458f-aa05-25cb8fa04435", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/aa4edeff-646b-4239-a6d5-2d611bdb4682", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/aad602c5-df77-4e4d-b2a4-5cf2d07df7ae", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/b8ae6926-9dad-4aa6-9c3d-7380bfeb1b8f", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/c3985f2e-8b19-4473-96fc-196203673044", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/c918aae8-c874-4664-acbc-d1cf944109b1", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/d7588720-280e-4ef6-bc4b-776d0a0ba3ab", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/e4d4a911-d0f4-4e4c-901e-a905a941fd68", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/e760b6cb-cf1a-4922-8e4d-6d5104751565", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/ed6c0ff4-d4ff-4a93-8009-4865888c3e43", + "passed": true, + "detail": 200 + }, + { + "check": "asset /resource-v2/media/fd4563da-eeb7-4518-87ea-efb2c7bd7b25", + "passed": true, + "detail": 200 + }, + { + "check": "asset /sites/cfn/icon.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /sites/cfn/images/banner/windows.jpg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /sites/cfn/images/logo/logo.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /upload/images/ad_fu.png", + "passed": true, + "detail": 200 + }, + { + "check": "37 published illustrations", + "passed": true, + "detail": 37 + }, + { + "check": "image integrity dog-spaniel-daisy-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS9BBZXFTM9KP5MFFGME21G-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-cat-moon-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-warm-cat-stretch-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-beagle-picnic-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-balanced-cat-walk-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYSA1ANR0FQ1CC23VT23GG10-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-dogs-dance-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-balanced-cat-rest-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-dalmatian-window-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-cat-vase-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYM9W6KF513WVC605KD2882D-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS9PBSVN4YG49YM9GFSA8QG-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS8TWGK0717VP03D6CHNFHT-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS95VTPPWF82N0N6Z4B2K4Z-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-corgi-laundry-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-poodle-cafe-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity 001-dog-terrier-slipper-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-warm-cat-sleep-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-shiba-doorstep-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cat-window-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-dog-dachshund-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-schnauzer-bicycle-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-bordercollie-kite-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cat-blue-chair-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-balanced-cat-watch-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS9GVB7VJV7NJH7DS0V5FPD-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-cat-fish-dream-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-dog-dalmatian-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-cat-collage-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-bulldog-bathmat-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS9VV3DJ5N8PNH98W1NC0Y3-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-warm-cat-pair-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-dachshund-terrace-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-tuxedo-cat-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-greyhound-cushion-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYSA6TVHXNZ93E5YKWYD6Y9H-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "only read-only image consumer active", + "passed": true, + "detail": null + }, + { + "check": "original pool and 160 fixed assignments preserved", + "passed": true, + "detail": 197 + }, + { + "check": "rejected yarn image absent", + "passed": true, + "detail": null + }, + { + "check": "production HEAD unchanged /www/wwwroot/clashfreenode-new.com", + "passed": true, + "detail": "0792297bb8164fd2929b939d8d1206bc77b4ee81" + }, + { + "check": "production HEAD unchanged /www/wwwroot/resource-v2/app", + "passed": true, + "detail": "77d4bb2b1737e668e28eb83699549b63c56b42d4" + }, + { + "check": "final closed API /api/article/receive", + "passed": true, + "detail": 404 + }, + { + "check": "final closed API /api/v1/telegram/hook", + "passed": true, + "detail": 404 + }, + { + "check": "final closed API /api/github/getlast", + "passed": true, + "detail": 404 + }, + { + "check": "final closed API /api/nasa/v1/category/base", + "passed": true, + "detail": 404 + }, + { + "check": "final closed API /api/editorial/v1/catalog", + "passed": true, + "detail": 404 + }, + { + "check": "search real HTTP returns tutorial matches", + "passed": true, + "detail": 200 + }, + { + "check": "search noindex", + "passed": true, + "detail": null + }, + { + "check": "final home and noindex", + "passed": true, + "detail": null + }, + { + "check": "existing public GitHub link retained", + "passed": true, + "detail": null + }, + { + "check": "read-only image credential denies assignment", + "passed": true, + "detail": 403 + }, + { + "check": "test DB account only test-schema CRUD", + "passed": true, + "detail": [ + [ + "fna_v3_test", + "SELECT" + ], + [ + "fna_v3_test", + "INSERT" + ], + [ + "fna_v3_test", + "UPDATE" + ], + [ + "fna_v3_test", + "DELETE" + ] + ] + } + ], + "environment": { + "env": "staging", + "db": "fna_v3_test", + "article_count": 184, + "category_count": 9, + "latest": { + "sSlug": "fn20261029", + "sTitle": "「10月29日」2026年最新高速SSR/V2ray/Clash/Shadowrocket免费节点订阅链接" + }, + "tutorials": [ + { + "sSlug": "m169", + "sTitle": "Clash Meta for Android 使用教程:导入订阅、选择节点与连接" + }, + { + "sSlug": "m174", + "sTitle": "Clash Verge Rev 使用教程:Linux 安装、订阅与代理设置" + }, + { + "sSlug": "m173", + "sTitle": "Clash Verge Rev 使用教程:Mac 安装、订阅与系统代理" + }, + { + "sSlug": "m167", + "sTitle": "从 Clash for Windows 迁移到 Clash Verge Rev" + }, + { + "sSlug": "m172", + "sTitle": "Mac 代理客户端下载指南:ClashX 与 Clash Verge Rev 怎么选" + }, + { + "sSlug": "mihomo-dns-leak", + "sTitle": "Clash 进阶:DNS 防泄漏配置与验证" + }, + { + "sSlug": "m170", + "sTitle": "Quantumult X 使用教程:iOS 安装、订阅导入与连接" + }, + { + "sSlug": "system-proxy-vs-tun", + "sTitle": "系统代理和 TUN 有什么区别?接管范围、使用选择与排错" + }, + { + "sSlug": "m171", + "sTitle": "v2rayNG 使用教程:Android 安装、导入订阅与连接" + }, + { + "sSlug": "clash-verge-rev-windows", + "sTitle": "Clash Verge Rev 使用教程:从安装到第一次连接(Windows)" + } + ], + "private_table_count": 0, + "user_rows": 0, + "editorial_disabled": true + }, + "resource_clients": [ + { + "id": 1, + "project": "fna-v3-import", + "scopes": "[\"read\",\"write\",\"publish\",\"share\"]", + "enabled": 0 + }, + { + "id": 2, + "project": "fna-v3", + "scopes": "[\"read\",\"write\"]", + "enabled": 0 + }, + { + "id": 3, + "project": "fna-v3", + "scopes": "[\"read\"]", + "enabled": 1 + } + ], + "passed": true, + "check_count": 292, + "failed_count": 0, + "asset_count": 55, + "verified_at": "2026-10-29T11:15:36Z" +} \ No newline at end of file diff --git a/docs/maintenance/PRODUCTION_VERIFICATION_2026-10-29.json b/docs/maintenance/PRODUCTION_VERIFICATION_2026-10-29.json new file mode 100644 index 00000000..d55ba932 --- /dev/null +++ b/docs/maintenance/PRODUCTION_VERIFICATION_2026-10-29.json @@ -0,0 +1,1721 @@ +{ + "checks": [ + { + "check": "production environment/debug/DB", + "passed": true, + "detail": null + }, + { + "check": "all_old_article_ids_retained", + "passed": true, + "detail": null + }, + { + "check": "old_urls_and_creation_dates_retained", + "passed": true, + "detail": null + }, + { + "check": "unrelated_article_core_fields_unchanged", + "passed": true, + "detail": null + }, + { + "check": "original_user_rows_unchanged", + "passed": true, + "detail": null + }, + { + "check": "184 or more total articles", + "passed": true, + "detail": 184 + }, + { + "check": "9 categories", + "passed": true, + "detail": 9 + }, + { + "check": "10 approved tutorials", + "passed": true, + "detail": null + }, + { + "check": "temporary editorial access closed", + "passed": true, + "detail": null + }, + { + "check": "production resource binding", + "passed": true, + "detail": null + }, + { + "check": "independent production search index", + "passed": true, + "detail": null + }, + { + "check": "approved production commit /www/wwwroot/clashfreenode-new.com", + "passed": true, + "detail": null + }, + { + "check": "approved production commit /www/wwwroot/resource-v2/app", + "passed": true, + "detail": null + }, + { + "check": "original Nginx unchanged clashfreenode.com.conf", + "passed": true, + "detail": null + }, + { + "check": "original Nginx unchanged resource-v2.gemcook.net.conf", + "passed": true, + "detail": null + }, + { + "check": "generated tags preserved at checkout", + "passed": true, + "detail": null + }, + { + "check": "production home HTTP200", + "passed": true, + "detail": 200 + }, + { + "check": "latest free-node home", + "passed": true, + "detail": "fn20261029" + }, + { + "check": "production home index/follow", + "passed": true, + "detail": null + }, + { + "check": "no test robots header on formal", + "passed": true, + "detail": null + }, + { + "check": "home no menu highlight", + "passed": true, + "detail": null + }, + { + "check": "formal canonical", + "passed": true, + "detail": null + }, + { + "check": "existing formal analytics restored", + "passed": true, + "detail": null + }, + { + "check": "no newly excluded advertising", + "passed": true, + "detail": null + }, + { + "check": "formal robots not block-all", + "passed": true, + "detail": null + }, + { + "check": "formal sitemap domain", + "passed": true, + "detail": null + }, + { + "check": "closed unconfigured editorial API", + "passed": true, + "detail": 503 + }, + { + "check": "page /freenode", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /freenode", + "passed": true, + "detail": null + }, + { + "check": "page /shadowrocketids", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "page /client", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /client", + "passed": true, + "detail": null + }, + { + "check": "page /advanced", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /advanced", + "passed": true, + "detail": null + }, + { + "check": "page /search/Clash", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "page /a/m169.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m174.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m173.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m167.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m172.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/mihomo-dns-leak.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m170.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/system-proxy-vs-tun.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/m171.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "page /a/clash-verge-rev-windows.html", + "passed": true, + "detail": 200 + }, + { + "check": "no test URL in public page /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /freenode", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /shadowrocketids", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /client", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /advanced", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /search/Clash", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m169.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m174.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m173.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m167.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m172.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/mihomo-dns-leak.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m170.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/system-proxy-vs-tun.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/m171.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "no dev asset /a/clash-verge-rev-windows.html", + "passed": true, + "detail": null + }, + { + "check": "asset /build/assets/app-BCx10ygF.css", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/app-Ba5joxXD.css", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/app-DDSp2ths.js", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-brands-400-BfBXV7Mm.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-brands-400-Bs6tcqqs.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-regular-400-BVHPE7da.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-regular-400-DRN8N0d1.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-solid-900-8GirhLYJ.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-solid-900-IAB4Droh.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-v4compatibility-CErXDOsT.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/fa-v4compatibility-DnhYSyY-.woff2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/iconfont-B3tZHDj4.ttf", + "passed": true, + "detail": 200 + }, + { + "check": "asset /build/assets/iconfont-D7mxe_Lh.woff", + "passed": true, + "detail": 200 + }, + { + "check": "asset /css/tutorials.css", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/clash-meta-android-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/dns-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/mac-client-guide-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/migration-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/quantumult-x-ios-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/system-proxy-tun-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/v2rayng-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/verge-import.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/verge-linux-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/verge-mac-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/verge-system-proxy.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /images/tutorials/windows-cover.svg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /sites/cfn/icon.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /sites/cfn/images/banner/windows.jpg", + "passed": true, + "detail": 200 + }, + { + "check": "asset /sites/cfn/images/logo/logo.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /upload/images/ad_fu.png", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/050d6878-df1f-467f-b9ce-19ff241e25ba", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/0ce3715f-afa3-47d4-b911-79bb36906d9c", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/137b455e-7adf-485c-8d28-a6e8ae6255d9", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/13c34280-92b0-454e-95b8-168916ebb47d", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/1d55b6e1-fc00-40df-b31d-fb9fc2b8c8dc", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/21f7e301-6e30-4daa-bcf4-e60d1f1e69e0", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/25a4e1e4-fdad-470a-873b-0e89194e6ad2", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/290cc8c1-7cc5-4a1e-9736-5510a50ed90f", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/2c98f3b6-d34b-4a15-8bd0-a2597faf2714", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/310393c8-a783-49d5-a908-90dabd092a2a", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/3626485a-47e2-4dad-b5eb-d233bf563297", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/3a89700b-8939-420b-9ab6-bf6b0d7e10ac", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/46d07f66-cf13-427e-b566-e39573968a8e", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/4d2686d2-bbb6-4826-9019-27004ad5b55f", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/58ea6fc8-f279-47a5-b23f-9553278bc0d3", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/62b1f9b1-14c0-49d4-9083-75bc10cdbf05", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/6a0512b9-f81c-433f-9852-4180ce02f58c", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/6f4c2087-fd5b-43de-a536-3217064b521f", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/85412e68-488d-4553-b17e-586c87612fdd", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/90d663e3-f413-4308-93ba-1908b281fe64", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/98b44958-4a28-420a-9bdf-57f3e7d7d800", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/a740b59f-cef1-40b6-b3ae-5eeb794eb009", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/a7f50b47-62aa-43e5-b037-094e76738cce", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/c0c93a21-881a-4995-b66f-ea0c1e0233f3", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/cb29bfd2-aa32-4290-b1c4-bf40631da564", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/d000d275-1a38-4051-ae3f-e811d2544795", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/d0a611ae-c9fe-4f91-af20-176a92a307c5", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/d848eda9-1763-46ea-9d04-0821b60b394a", + "passed": true, + "detail": 200 + }, + { + "check": "asset /media/ec7f3234-e209-4663-b474-27f344952275", + "passed": true, + "detail": 200 + }, + { + "check": "37 production illustration publications", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-spaniel-daisy-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS9BBZXFTM9KP5MFFGME21G-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-cat-moon-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-warm-cat-stretch-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-beagle-picnic-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-balanced-cat-walk-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYSA1ANR0FQ1CC23VT23GG10-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-dogs-dance-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-balanced-cat-rest-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-dalmatian-window-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-cat-vase-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYM9W6KF513WVC605KD2882D-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS9PBSVN4YG49YM9GFSA8QG-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS8TWGK0717VP03D6CHNFHT-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS95VTPPWF82N0N6Z4B2K4Z-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-corgi-laundry-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-poodle-cafe-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity 001-dog-terrier-slipper-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-warm-cat-sleep-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-shiba-doorstep-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cat-window-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-dog-dachshund-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-schnauzer-bicycle-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-bordercollie-kite-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cat-blue-chair-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-balanced-cat-watch-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS9GVB7VJV7NJH7DS0V5FPD-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-cat-fish-dream-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-dog-dalmatian-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity freenode-cat-collage-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-bulldog-bathmat-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYS9VV3DJ5N8PNH98W1NC0Y3-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-warm-cat-pair-20261026.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-dachshund-terrace-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity cfn-tuxedo-cat-20261023.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity dog-greyhound-cushion-20261028.webp", + "passed": true, + "detail": null + }, + { + "check": "image integrity tg_image__maomi_a-01KYSA6TVHXNZ93E5YKWYD6Y9H-1-full.jpg", + "passed": true, + "detail": null + }, + { + "check": "rejected image remains excluded", + "passed": true, + "detail": null + }, + { + "check": "only project-scoped read/write runtime client active", + "passed": true, + "detail": null + }, + { + "check": "approved preview fixed assignments retained", + "passed": true, + "detail": null + }, + { + "check": "formal consumer assignment idempotency", + "passed": true, + "detail": null + }, + { + "check": "runtime client cannot publish assets", + "passed": true, + "detail": 403 + }, + { + "check": "existing Resource assets rows unchanged", + "passed": true, + "detail": 5 + }, + { + "check": "existing Resource clients rows unchanged", + "passed": true, + "detail": 20 + }, + { + "check": "original ingestion POST routes preserved", + "passed": true, + "detail": null + }, + { + "check": "test preview remains noindex", + "passed": true, + "detail": null + } + ], + "base_url": "https://clashfreenode.com", + "environment": { + "environment": "production", + "debug": "false", + "base_url": "https://clashfreenode.com", + "not_test_db": true, + "article_count": 184, + "category_count": 9, + "latest": { + "sSlug": "fn20261029", + "sTitle": "「10月29日」2026年最新高速SSR/V2ray/Clash/Shadowrocket免费节点订阅链接" + }, + "tutorials": [ + { + "id": 206, + "sSlug": "m169", + "sTitle": "Clash Meta for Android 使用教程:导入订阅、选择节点与连接", + "created_at": "2026-08-04 10:21:04" + }, + { + "id": 211, + "sSlug": "m174", + "sTitle": "Clash Verge Rev 使用教程:Linux 安装、订阅与代理设置", + "created_at": "2026-08-04 10:21:23" + }, + { + "id": 210, + "sSlug": "m173", + "sTitle": "Clash Verge Rev 使用教程:Mac 安装、订阅与系统代理", + "created_at": "2026-08-04 10:21:19" + }, + { + "id": 212, + "sSlug": "m167", + "sTitle": "从 Clash for Windows 迁移到 Clash Verge Rev", + "created_at": "2026-08-04 10:24:04" + }, + { + "id": 209, + "sSlug": "m172", + "sTitle": "Mac 代理客户端下载指南:ClashX 与 Clash Verge Rev 怎么选", + "created_at": "2026-08-04 10:21:15" + }, + { + "id": 375, + "sSlug": "mihomo-dns-leak", + "sTitle": "Clash 进阶:DNS 防泄漏配置与验证", + "created_at": "2026-10-29 11:47:13" + }, + { + "id": 207, + "sSlug": "m170", + "sTitle": "Quantumult X 使用教程:iOS 安装、订阅导入与连接", + "created_at": "2026-08-04 10:21:08" + }, + { + "id": 376, + "sSlug": "system-proxy-vs-tun", + "sTitle": "系统代理和 TUN 有什么区别?接管范围、使用选择与排错", + "created_at": "2026-10-29 11:47:13" + }, + { + "id": 208, + "sSlug": "m171", + "sTitle": "v2rayNG 使用教程:Android 安装、导入订阅与连接", + "created_at": "2026-08-04 10:21:12" + }, + { + "id": 377, + "sSlug": "clash-verge-rev-windows", + "sTitle": "Clash Verge Rev 使用教程:从安装到第一次连接(Windows)", + "created_at": "2026-10-29 11:47:13" + } + ], + "all_old_article_ids_retained": true, + "old_urls_and_creation_dates_retained": true, + "unrelated_article_core_fields_unchanged": true, + "original_user_rows_unchanged": true, + "editorial_disabled": true, + "resource_enabled": true, + "resource_url": "https://resource-v2.gemcook.net", + "search_index": "cfn_articles_v3" + }, + "resource_clients": [ + { + "id": 21, + "project": "fna-v3-illustrations", + "scopes": "[\"read\",\"write\",\"publish\",\"share\"]", + "enabled": 0 + }, + { + "id": 22, + "project": "fna-v3", + "scopes": "[\"read\",\"write\"]", + "enabled": 1 + } + ], + "passed": true, + "check_count": 323, + "failed_count": 0, + "asset_count": 59, + "verified_at": "2026-10-29T11:50:13Z" +} \ No newline at end of file diff --git a/docs/maintenance/RELEASE_PREFLIGHT_2026-10-28.md b/docs/maintenance/RELEASE_PREFLIGHT_2026-10-28.md new file mode 100644 index 00000000..e98dbe17 --- /dev/null +++ b/docs/maintenance/RELEASE_PREFLIGHT_2026-10-28.md @@ -0,0 +1,124 @@ +# FNA_V3 发布前核对 · 2026-10-28 + +状态:2026-10-29用户确认test“没问题,切到正式”,现已完成正式切换及323项服务器侧验收,0失败。正式入口https://clashfreenode.com/;test仍独立保留并禁止索引。新增广告未发布。以下test与准备段落保留其历史时点含义。 + +## 正式切换(2026-10-29) + +用户已在test页面确认后明确授权切正式。本次复用原生产目录、数据库、域名及Nginx块,不将test数据库、会话或密钥替代生产;其他同代码正式实例不在范围。 + +- cfn:/www/wwwroot/clashfreenode-new.com,检出已推送且经过test确认的76141453bbdbd14b13c69647c14226bae7250afc,功能代码固定为此提交,后续仅AGENTS/docs维护提交可推进部署HEAD,不改变已验收应用代码。现有生产仓库为tom/fn_b.git,发布分支codex/fna-v3-release-20261029;本地复制历史不直接推送。Resource V2:/www/wwwroot/resource-v2/app,检出0d9e71a0cdbf9b6e298dc28b28ccc38879a5808e。两者沿先前codex/fna-v3-release-20261029推送提交发布,不通过源码包覆盖。原generated-tags-cloud未提交模板逐字保留;既有cron没有Git自动更新命令,未改计划。 +- 已在原库上追加指定5张editorial表,限定更新client/advanced/shadowrocketids元数据。10篇教程从用户确认的test实际公开正文冻结,经生产临时凭据完成草稿→逐篇签名预览→同hash发布→回执核对;原7篇ID/slug/创建时间保留,新增3篇。当前184篇文章、9分类;原181篇全部保留,174篇非本次编辑文章的标题/摘要/正文/原始封面字段/分类/状态/日期全部逐项不变,原账号行一致。 +- 原生产APP_ENV=local、DEBUG开启,现限定修正production/DEBUG=false;原DB、APP_KEY、会话、通知和其他配置保留。资源绑定https://resource-v2.gemcook.net,搜索改用专属cfn_articles_v3并完整初始化,原articles索引不删除。正式站原统计恢复,首页index/follow、正式canonical/robots/sitemap均通过;没有将test的全站noindex、API封闭或独立会话配置复制到正式。 +- Resource仅追加已验证的图池代码/表,37张审核展示图按API上传/发布/授权;从test已确认状态恢复213条池/固定选择/游标引用,22猫/15狗,84篇免费节点/90篇免费苹果ID。所有已确认固定配图按SHA逐项保留;毛线球猫继续排除。原Resource的5个资产及20个历史客户端记录全部不变。 +- Resource临时图片所有者21(read/write/publish/share)已在同操作finally撤销并删除密钥文件;仅正式fna-v3消费者22保持read/write,用于日更接收时创建持久配图,不含publish/share/delete。密钥只在服务器私有客户端文件及主站storage/app/private/illustrations.json,0600,不复制测试凭据。真实旧文章重复分配返回原图且不推进cursor,消费者发布权限403。 +- 生产编辑临时密钥迁移后已删除,EDITORIAL_API_ENABLED=false,未留下可调用的无授权编辑接口;后续明确写作/发布任务按EDITORIAL_API.md流程临时启用并关闭。本次没有执行真实日更接收、Telegram通知或IndexNow;只核对原3条POST接收路由保留,并对相同图池服务的既有文章键做幂等验收。 +- 新增DPL/HN/FUC广告组件/配置/CSS/图片仍排除,保留生产原有广告。主站及Resource原Nginx配置逐字未变,未改正式DNS或证书;test继续独立noindex。软件资源服务与其他正式实例未动。 + +### 备份、验收与恢复 + +切换前私有恢复点为VPS-003:/root/backups/cfn-fna-v3-20261029/production/(700/600):两个Git基线bundle、原.env、两个Nginx文件、原生成模板、生产代码/构建归档、18表/181篇一致性数据库快照、state-before.json;无生产秘密导出本机。Resource原生一致性备份为/www/wwwroot/resource-v2/app/storage/app/private/backups/20261029-113946-ee837e82-40f5-4085-8641-2c06c72c3e3c,含SQLite及资产哈希清单。 + +生产resource-receipt.json、cutover-receipt.json、editorial-operation.json记录各步骤/草稿与发布UUID;未知结果先查原UUID,不盲目重复发布。2026-10-29 11:50:13 UTC服务器侧323项检查全部通过,含59个页面引用资源和37张公开图片hash;非秘密结果见[正式验收JSON](PRODUCTION_VERIFICATION_2026-10-29.json)。test此前292项验收另留原件。用户已确认test页面,AI未做正式线上页面验收,不能把服务器侧验收写成正式页面验收。 + +回退必须先识别回退范围和上线后新增数据,不自动执行:保留现有184篇及后续文章;代码可固定回0792297bb8164fd2929b939d8d1206bc77b4ee81,但先保留已发布教程CSS/图片、恢复原构建清单所需文件,避免回退Git时删除仍被文章引用的资源。Resource服务与已发布media地址继续保留;不要drop新增表、撤回被文章引用图片或整库覆盖上线后的新数据。若仅关闭图池,设置RESOURCE_V2_ILLUSTRATIONS_ENABLED=false并清配置/响应缓存,恢复原字段展示。正文恢复走本站版本回退API,原7篇基线版本0已保存;新增文章不做无授权删除。APP_ENV=production/DEBUG=false维持,不能为代码回退重新开放调试。 + + +## 当前门槛:先test预览,确认后再切正式(2026-10-29) + +本节为此前test部署记录;用户现已确认,正式切换结果以上节为准。 + +用户最新要求先部署test子域名,确认无误后才切正式;此前正式发布授权按这个新顺序执行,当前不得切换正式站。本次新增广告继续排除。 + +已完成: + +- Cloudflare ACC-001界面确认clashfreenode.com区域归属,zone ID为e3145aaaca4ca16b96855abc80e3e92f;仅新增test A→45.153.247.44,DNS-only、自动TTL。原主域名/www和邮件记录未修改。配置截图为/private/tmp/fna-release-20261029/test-dns.png。 +- 在VPS-003生产历史的隔离分支codex/fna-v3-release-20261029构造提交并真实推送:cfn为76141453bbdbd14b13c69647c14226bae7250afc,Resource V2为0d9e71a0cdbf9b6e298dc28b28ccc38879a5808e。仓库沿目标服务器原origin,仅推送新分支,未修改正式分支或正式checkout。 +- 新目录/www/wwwroot/fna-v3-test与/www/wwwroot/fna-v3-test-resource分别检出上述SHA;现已启用各自运行.env、独立数据库/存储及test HTTPS虚拟主机。代码暂存传输用于构造Git提交,实际预览目录由Git检出,未以源码归档覆盖正式站。 +- cfn提交排除新增广告组件/配置/CSS/图片,保留生产既有侧栏广告位置;带首页、教程、独立编辑API、插画消费者及构建产物。Resource提交只增加图池控制器、图片健康检查、关联表迁移及两条图池路由,不包含软件下载业务。 +- staging图片来源只接受https://test.clashfreenode.com/resource-v2,production仍只接受原Resource V2生产地址;staging模板noindex/nofollow并关闭正式站统计脚本。21项测试157断言通过。 +- 本地私有暂存已选出10篇教程、栏目元数据,以及当前37张公开展示图片和199个pool/selection/cursor引用;未传送线上数据到本机,未恢复已排除毛线球猫。 + +用户在逐项范围说明后明确回复“继续啊”,已按批准范围完成: + +1. 创建独立fna_v3_test库,只复制181篇公开文章、8个启用分类、25个标签及1409个关联,不复制用户、密码、会话、队列或点赞IP/指纹。为既有ORM查询建立空users和article_likes结构,users实际0行,无管理账号或会话。指定editorial五表在test安装。 +2. 独立数据库账号仅SELECT/INSERT/UPDATE/DELETE,限定fna_v3_test;没有其他库或DDL权限,现场查询验证通过。应用以staging运行,主PHP-FPM实际账号为nginx(现场核实),test.env为root:nginx 0640,私有消费者凭据0600;独立资源服务使用resourcev2账号。 +3. 测试Resource使用独立SQLite、存储、37张审核通过的展示图;不导入原PNG、提示词或其他资源。通过API恢复37条pool、160条selection及2条原cursor引用,再为生产快照多出的14篇资源文章配图;现84篇免费节点、90篇免费苹果ID。原197条pool/selection逐项按图片SHA验证不变,cursor只随新增文章正常推进。猫22/狗15,毛线球猫未恢复。临时所有者客户端1和写消费者2在同一次操作finally中撤销并移除凭据文件,只保留本测试SQLite的fna-v3只读客户端3;真实写分配请求403。 +4. 栏目定点迁移client/advanced/shadowrocketids,10篇教程经临时编辑密钥完成草稿→逐篇签名预览→同hash发布→回执核对,保留7个旧slug、追加3篇。完成后test共184篇、9分类。搜索独立fna_v3_test_articles已重建,真实/search/Clash返回教程。临时编辑密钥已移除,EDITORIAL_API_ENABLED=false;所有/api/应用旧接口在test Nginx统一404,resource-v2独立API仅受限鉴权使用。未启动队列、定时任务、通知或IndexNow。 +5. 独立/etc/nginx/conf.d/test.clashfreenode.com.conf启用HTTP→HTTPS,证书由Let’s Encrypt签发,至2027-01-27,沿现有Certbot续期;保留ACME webroot。整站X-Robots-Tag:noindex,nofollow,HTML同样noindex,robots禁止抓取;关闭正式Umami统计,独立缓存/会话,保留已有公开GitHub链接。Nginx配置校验通过后reload,未修改正式站server块、代码、数据库或证书。 + +验收:2026-10-29 11:15:36 UTC,292项通过、0失败;包含首页最新fn20261029及不高亮菜单、4栏目、10教程、真实搜索、55个引用资源、37张图片完整哈希、历史固定配图、API隔离、权限撤销及正式两个Git HEAD未变。公开预览为https://test.clashfreenode.com/。已完成服务器侧验收,未做线上页面验收,等待用户自行确认后才可切正式。非秘密结果见[验收JSON](PREVIEW_VERIFICATION_2026-10-29.json),服务器私有导入回执和验收原件在/root/backups/cfn-fna-v3-20261029/,不包含在公开站点根目录。 + +此前自动审批拒绝完整Nginx输出、整库复制及不在同命令撤销的临时凭据方案;已分别改为字段白名单、公开内容最小快照及同操作try/finally创建/使用/撤销,用户明确继续后执行。Git认证仅在内存中经私有Unix socket一次性传递,未保存Git密码文件。这些阻塞在test部署时解除;随后用户确认并授权切正式,执行结果见上方正式切换。 + +回退范围:仅撤销本次test DNS记录、test虚拟主机及其独立运行资源;保留私有回执和Git提交供恢复,不能恢复整库覆盖正式站。正式切换必须等用户确认本次预览后再执行。 + +## 本次更新 + +| 范围 | 当前本地结果 | 发布时需要携带 | +| --- | --- | --- | +| 首页 | 展示日期最新的已发布免费节点文章全文,不限当天,排除未来文章;首页不高亮免费节点菜单;免费节点页保留历史列表 | 控制器、服务、路由、菜单及首页缓存策略 | +| 教程栏目 | 客户端改为入门教程,新增综合教程;栏目横幅沿用原样式,修正全栏目计数 | 分类数据、模板及CSS | +| 教程正文 | 共10篇长期文章:原7篇重写/重分类,新增Windows纯入门、DNS防泄漏、系统代理与TUN;加入图解、封面及真实内链,清除内部验收口吻 | 正文源、公开文章数据、分类、资源和编辑版本,不是仅上传Markdown | +| 广告 | DPL与Hardnerd广告;HN当前为首字母大写、纯黑背景静态横幅,扫光已撤回 | 广告组件、CSS、实际引用图及生产链接配置 | +| 插画 | 本地Resource V2图池与文章固定配图,免费节点用猫、小火箭ID用狗;已去除用户拒绝的粉底毛线球猫,4篇定点换图 | 生产素材、授权、图池、固定分配及可用于production的消费者 | +| 独立文章API | 本站草稿、签名预览、按hash发布、显式旧文接管、版本/回执、回退、图片与内链校验;不经过ATOM | 新增迁移、独立生产密钥、基址与搜索配置、生产内容迁移流程 | +| 搜索 | 本地独立fna_v3_articles,编辑API具有缓存/搜索/sitemap后续处理回执 | 明确生产索引和初始化,不能直接复制本地索引名或未知共享索引 | +| SEO | 完成建议清单,首页和部分教程改造已实施 | 不能将36项SEO清单整体标为完成 | + +当前本地数据库170篇文章,其中160篇自动资源文章、10篇长期教程,分类9个。十篇教程实际路径:m169、m170、m171、m172、m173、m174、m167、mihomo-dns-leak、clash-verge-rev-windows、system-proxy-vs-tun(均在/a/下,以.html结尾)。稳定关系以[写作索引](../content/WRITING.md)为准。 + +## 本次重新验证 + +- `vendor/bin/phpunit --process-isolation tests/Feature/LatestFreeNodeHomeTest.php tests/Feature/EditorialApiTest.php`:19项测试、149条断言通过。 +- `npm run build`:成功,137个模块;manifest及CSS/JS构建产物已生成。构建后恢复原public/hot,保留本地5187开发预览。 +- 关键新增PHP语法及本次代码diff空白检查通过。这些结果不等于全部业务、生产API或生产图片已验收。 +- 首页noindex已于2026-10-28修复:按首页路由独立返回`index, follow`,无额外X-Robots-Tag;旧文章详情仍按原规则noindex,栏目仍index,三条本地HTTP实测通过。签名预览仍优先noindex,nofollow。 +- 候选文件清单及SHA256:`output/release-preflight-20261028/candidate-manifest.json`,当前76个候选文件。它不是最终提交白名单,其中含需进一步筛选的历史广告/素材;不含私密环境文件。 + +## 线上只读现场 + +2026-10-28通过本机SSH→白色机→VPS-003,只读核对登记目录及数据库;无线上HTTP请求,无服务器配置或业务写入。 + +- cfn目录:`/www/wwwroot/clashfreenode-new.com`,展示域名clashfreenode.com。 +- 当前Git HEAD:`0792297bb8164fd2929b939d8d1206bc77b4ee81`。线上不存在本地基线4778ca17,不能按两者共用历史直接pull/覆盖。 +- 线上有未提交的`resources/views/components/generated-tags-cloud.blade.php`,发布前保留并识别生成方式。 +- 线上PHP CLI 8.5.2,public/build/manifest.json存在;FPM与队列/调度配置本次未重新核实。 +- 线上178篇文章,最新为ssi20261028;分类仍为8个、client名称为客户端,尚无advanced;editorial_documents表不存在。 +- 本地仅170篇且自动资源快照更旧,绝对不能用本地整库覆盖线上178篇。必须保留生产新增节点、小火箭ID、点赞等数据,只定点迁移教程/分类/编辑表。 + +## 发布前必须解决 + +1. **发布仓库及生产差异。** 本地HEAD4778ca17,唯一remote为复制来的FN_B仓库;线上历史独立。需先取得生产文件差异并明确本项目发布仓库/分支,再生成只包含本次范围的提交。未经确认不向旧FN_B remote推送。 +2. **提交卫生。** 当前仓库已跟踪8588个vendor文件、10046个node_modules文件及`_env/.env`。不将本地私密配置、缓存、旧环境文件、输出截图、临时回执或整个依赖目录混入本次发布;不能靠新增.gitignore自动清除历史跟踪。若建立新仓库,使用清洁发布树而非复制原Git历史。 +3. **图片生产接入。** IllustrationPool明确只允许local且基址为resource.loc:8612。直接部署会继续使用旧图,不能兑现本地视觉。生产Resource V2已有独立服务登记,但图池接口/素材、消费者授权和生产兼容未在本次部署;须单独准备并验收。不能把.loc地址写入生产。 +4. **教程及分类定点迁移。** 需按旧slug比对并显式接管7篇,新增3篇,创建/映射综合教程分类;迁移关联、封面和图片。生产ID由现场分配,不使用本地ID硬覆盖。先保存生产基线并生成可审核差异,普通编辑正文通过本站API的草稿→预览→hash发布完成。 +5. **文章API生产配置。** 仅追加指定editorial表迁移;默认生产关闭。setup命令仅支持本地,须另行准备生产专用凭据,绑定真实环境和base_url,并确定生产搜索服务/独立索引。不复制本地密钥,不执行migrate:fresh。 +6. **首页索引策略。** 首页继承老文章7天noindex的问题已本地修复并验收;该阻塞解除。首页与日更详情的canonical关系仍属于SEO-004/018剩余规则,本次未改。 +7. **HN广告地址。** 生产未配置HN_AD_URL时HN不展示;本地默认hn.loc不能作为线上目标。上线配置必须给出已登记真实地址,不能猜域名。 +8. **正式备份与回滚。** 上线动作前备份目标代码提交/未提交文件、生产数据库和站点配置;保存只读核对结果。代码与资源分别按明确Git提交部署,正文更新保存API基线版本。回滚代码不drop新增编辑表;内容按版本回退,不恢复整库覆盖上线后的新文章。 + +## 执行顺序 + +先完成生产差异清单和发布仓库选择,再处理图片/首页SEO/环境配置,完成隔离验收与定点数据预演;之后生成可审阅提交、备份清单和回滚命令。正式发布按提交→推送→目标服务器更新到该提交→指定迁移→API定点内容发布→服务器侧验收执行。当前未开始后半段操作。 + +线上页面验收未做;此次为准备工作,不将未发布状态写成服务器侧业务验收通过。用户若要求线上页面验收,仍须按Windows入口访问审批执行。 + +## 2026-10-29 继续发布:早期准备记录(已由上方test部署状态更新) + +用户已授权继续发布全部关联更新,但本次排除广告;不发布DPL/HN/FUC新增组件、图片、CSS或链接,保留生产现有广告。这个范围不要求从本地删除广告实现。 + +已在VPS-003创建/root/backups/cfn-fna-v3-20261029/,生产代码备份code-before.tar.gz和Git基线baseline.bundle已确认完成;生产HEAD仍为0792297bb8164fd2929b939d8d1206bc77b4ee81,运行分支master,只有原generated-tags-cloud模板未提交修改。没有提交、推送、切换版本或迁移生产数据。 + +自动审批拒绝把完整生产Git基线导出本机;该路线已停止,后续改为服务器隔离工作区构造提交、推送后目标站点按明确SHA更新,不需要导出完整生产仓库。随后白色机104.168.30.40:22连续在SSH密钥交换前关闭连接,未进入密码认证。数据库备份和隔离工作区创建命令均未执行成功,不能视为已有完整回滚条件;恢复连接后先核对备份和现场状态再继续,不能跳过数据库备份。 + +关联Resource V2线上仍为77d4bb2b1737e668e28eb83699549b63c56b42d4,尚无PoolController、ImageHealth、CatalogController及其新增迁移;本次必须通过Git补发图池相关功能,不能只复制素材或假设生产已有池API。软件资源独立实例不在本次更新范围。 + +FNA_V3已本地准备图片消费者生产适配:仅local精确允许http://resource.loc:8612、production精确允许https://resource-v2.gemcook.net;其余环境/来源禁用。新增RESOURCE_V2_ILLUSTRATIONS_ENABLED开关,生产需显式配置和独立凭据;本次尚未启用生产服务。实现未触碰本地现有配图和文章数据。回归19项/149断言通过;环境边界另有IllustrationEnvironmentTest专项验证。 + +后续:补做数据库/Resource V2备份→服务器隔离工作区合并并排除广告→测试与Git提交/推送→Resource V2图池增量部署/素材迁移→cfn代码部署与指定表迁移→教程API定点发布→服务器侧验收。未绕过白色机直连。 + +### 白色机连接复核(2026-10-29 10:12 UTC) + +按用户要求只读排查:本机到白色机经utun6/Clash TUN,运行时为global、当前GLOBAL选择日本JP-07;这是当前链路证据,不能单凭它认定代理故障。随后已收到正常OpenSSH横幅,真实登录白色机成功,并通过登记跳转真实登录VPS-003成功。 + +白色机ssh服务active,ActiveEnterTimestamp为2026-10-15,NRestarts=0;MaxStartups=10:30:100。近期服务日志未找到MaxStartups丢弃/限流记录。此前失败发生在认证前,目前仅能定性为间歇断连,具体根因未定位,不能归因于密码错误、服务器封禁或代理节点。全程没有切换节点、关闭TUN、重启SSH或修改防火墙。连接阻塞已解除;本次连接诊断没有执行新的发布或数据库写入,完整发布仍未完成。 diff --git a/docs/maintenance/SEO_BASELINE_2026-10-22.json b/docs/maintenance/SEO_BASELINE_2026-10-22.json new file mode 100644 index 00000000..309be343 --- /dev/null +++ b/docs/maintenance/SEO_BASELINE_2026-10-22.json @@ -0,0 +1,986 @@ +{ + "schema": "fna-v3.seo-audit.v1", + "audit_date": "2026-10-22", + "timezone": "Asia/Shanghai", + "data_captured_utc": "2026-10-22T05:10:40+00:00", + "scope": "Local read-only audit; project online requests blocked; no ranking or indexing claims", + "git_head": "4778ca17d1a722f375d15219cff13cea8946ab26", + "source_hashes": { + "routes/web.php": "55f0e86fbf572be3688e680b5acf3b2a6140f3b30d76e92fb3b07d5446a00f02", + "app/Services/ArticlesService.php": "f811dc93f106cddd4172bd6b10378f61c9906459e81dce42704a94b69e548a81", + "app/Http/Controllers/Web/ArticlesController.php": "687fdf307930403392e3b28846f3af88a7a7e2a09dd456f32682fae7fe425f69", + "resources/views/components/app-layout.blade.php": "e38d8008e2082d4c47fa62831efb83ed10b407e71026af25ee27b85c6da3303c", + "resources/views/pages/articles/default/index.blade.php": "d2b94473c307d418e24761b3ef9a1b641c7260388b1ce7654e9a3a2ede4c494e", + "resources/views/pages/articles/default/show.blade.php": "f0dea8dca71bdae27fe4a5fdb1bbcb9a44f483839dd456deffd82b6c2faedd18", + "resources/js/app.js": "eb3e861c110249a7b30d798597c94c398953b5ff9cd878b1e88f50834139fac7", + "app/Http/Controllers/SitemapController.php": "4274dcbb483097a3392c96fda375301026829bde88360472a5697bcfe4446a18", + "app/Http/Controllers/RobotsController.php": "f18e708dd3fb5ed12460bf383e008057858f5dd3c46839e8b52b63d1e54788bb", + "app/Models/Articles.php": "60ea10d16fc3b086f40fce907056918cbf310f4d04e675917a033e7152d2bb03", + "app/Console/Commands/ClearDb.php": "c962d3a8a54344930781d990f7d1a7031c9b795e6cf3a6afe58d95c942ce35f1", + "resources/views/components/dpl-article-ad.blade.php": "0957c68b8735726a3dfff07f67755ef79c8b2f19784f01cf6e3f890edc665698" + }, + "article_count": 167, + "categories": [ + { + "id": 1, + "iParentId": 0, + "sName": "免费节点", + "sSlug": "freenode", + "iStatus": 1, + "iShowChildren": 0, + "options": { + "noindexday": "7" + }, + "articles": 78, + "expired": 72 + }, + { + "id": 2, + "iParentId": 0, + "sName": "客户端", + "sSlug": "client", + "iStatus": 1, + "iShowChildren": 1, + "options": null, + "articles": 0, + "expired": 0 + }, + { + "id": 3, + "iParentId": 2, + "sName": "Windows", + "sSlug": "windows", + "iStatus": 1, + "iShowChildren": 0, + "options": null, + "articles": 1, + "expired": 0 + }, + { + "id": 4, + "iParentId": 2, + "sName": "Andorid", + "sSlug": "andorid", + "iStatus": 1, + "iShowChildren": 0, + "options": null, + "articles": 2, + "expired": 0 + }, + { + "id": 6, + "iParentId": 2, + "sName": "Ios", + "sSlug": "ios", + "iStatus": 1, + "iShowChildren": 0, + "options": null, + "articles": 1, + "expired": 0 + }, + { + "id": 7, + "iParentId": 2, + "sName": "Linux", + "sSlug": "linux", + "iStatus": 1, + "iShowChildren": 0, + "options": null, + "articles": 1, + "expired": 0 + }, + { + "id": 8, + "iParentId": 2, + "sName": "Mac", + "sSlug": "mac", + "iStatus": 1, + "iShowChildren": 0, + "options": null, + "articles": 2, + "expired": 0 + }, + { + "id": 9, + "iParentId": 0, + "sName": "免费小火箭ID", + "sSlug": "shadowrocketids", + "iStatus": 1, + "iShowChildren": 0, + "options": { + "noindexday": "7" + }, + "articles": 82, + "expired": 76 + } + ], + "tags": [ + { + "id": 5, + "sName": "Shadowrocket", + "sSlug": "shadowrocket-7vf7o", + "count": 160 + }, + { + "id": 7, + "sName": "Clash", + "sSlug": "clash-wd81q", + "count": 83 + }, + { + "id": 19, + "sName": "Ios", + "sSlug": "ios-nmR1P", + "count": 83 + }, + { + "id": 29, + "sName": "免费苹果账号", + "sSlug": "mian-fei-ping-guo-zhang-hao-rlB6M", + "count": 82 + }, + { + "id": 26, + "sName": "小火箭", + "sSlug": "xiao-huo-jian-2WpM6", + "count": 82 + }, + { + "id": 28, + "sName": "shadowrocket id", + "sSlug": "shadowrocket-id-ds9Uw", + "count": 82 + }, + { + "id": 27, + "sName": "小火箭账号", + "sSlug": "xiao-huo-jian-zhang-hao-5QgoQ", + "count": 82 + }, + { + "id": 12, + "sName": "v2ray", + "sSlug": "v2ray-Pd4HR", + "count": 79 + }, + { + "id": 6, + "sName": "Quantumult", + "sSlug": "quantumult-Ggc90", + "count": 79 + }, + { + "id": 8, + "sName": "SSR", + "sSlug": "ssr-BjeEq", + "count": 79 + }, + { + "id": 10, + "sName": "订阅链接", + "sSlug": "ding-yue-lian-jie-ruNF0", + "count": 78 + }, + { + "id": 15, + "sName": "Hiddify", + "sSlug": "hiddify-ryEsf", + "count": 78 + }, + { + "id": 9, + "sName": "节点", + "sSlug": "jie-dian-yIt5z", + "count": 78 + }, + { + "id": 11, + "sName": "免费节点", + "sSlug": "mian-fei-jie-dian-hOpYo", + "count": 78 + }, + { + "id": 16, + "sName": "SingBox", + "sSlug": "singbox-A2Zpo", + "count": 78 + }, + { + "id": 13, + "sName": "客户端", + "sSlug": "ke-hu-duan-oAK85", + "count": 5 + }, + { + "id": 18, + "sName": "安卓", + "sSlug": "an-zhuo-2MYr2", + "count": 5 + }, + { + "id": 17, + "sName": "Android", + "sSlug": "android-xSKGC", + "count": 2 + }, + { + "id": 24, + "sName": "mac", + "sSlug": "mac-FWuEm", + "count": 2 + }, + { + "id": 21, + "sName": "iPhone", + "sSlug": "iphone-CZDcr", + "count": 1 + }, + { + "id": 23, + "sName": "苹果", + "sSlug": "ping-guo-5a23n", + "count": 1 + }, + { + "id": 20, + "sName": "iPad", + "sSlug": "ipad-FJbiU", + "count": 1 + }, + { + "id": 25, + "sName": "linux", + "sSlug": "linux-U82BL", + "count": 1 + }, + { + "id": 14, + "sName": "windows", + "sSlug": "windows-Z3oeN", + "count": 1 + }, + { + "id": 22, + "sName": "Quantumult X", + "sSlug": "quantumult-x-ub5dy", + "count": 1 + } + ], + "database_clock": { + "db_now": "2026-10-22 13:10:40", + "db_utc": "2026-10-22 05:10:40", + "db_timezone": "SYSTEM" + }, + "config": { + "page_limit": 2, + "response_cache_enabled": false, + "response_cache_seconds": 604800, + "app_url_origin": "fn-b.loc", + "scout_driver": "meilisearch", + "scout_prefix": "", + "search_host": "127.0.0.1" + }, + "http_summary": { + "requests": 230, + "status": { + "200": 227, + "404": 3 + }, + "article_robots": { + "noindex, follow": 148, + "index, follow": 19 + }, + "sitemap_urls": 20, + "sitemap_noindex_conflicts": [], + "html_graph_reachable_articles": 12, + "html_graph_unreached_articles": 155, + "html_graph_unreached_indexable_articles": [ + "/a/fn20261016.html", + "/a/fn20261017.html", + "/a/fn20261018.html", + "/a/ssi20261016.html", + "/a/ssi20261017.html", + "/a/ssi20261018.html", + "/a/ssi20261019.html" + ], + "max_observed_graph_depth": 3, + "list_titles_distinct": 1 + }, + "http_examples": [ + { + "path": "/", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/?page=1", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/?page=2", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [ + "/a/fn20261019.html", + "/a/fn20261018.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/?page=0", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/?page=-1", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/?page=abc", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/?page=39", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [ + "/a/fn20260731.html", + "/a/fn20260730.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/?page=40", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/?page=99", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103" + ], + "h1": [], + "cards": [], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/freenode", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/freenode" + ], + "h1": [], + "cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/wrong/freenode", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/wrong/freenode" + ], + "h1": [], + "cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/client", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/client" + ], + "h1": [], + "cards": [ + "/a/m167.html", + "/a/m174.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/client/windows", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/client/windows" + ], + "h1": [ + "windows1" + ], + "cards": [ + "/a/m167.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/windows", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/windows" + ], + "h1": [ + "windows1" + ], + "cards": [ + "/a/m167.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/wrong/windows", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/wrong/windows" + ], + "h1": [ + "windows1" + ], + "cards": [ + "/a/m167.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/a/client", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/a/client" + ], + "h1": [], + "cards": [ + "/a/m167.html", + "/a/m174.html" + ], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/search/Clash", + "status": 200, + "title": "Clash免费节点,支持Clash/V2ray/Singbox/小火箭/Hiddify,每天更新。 - v2rayfreenode", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/search/Clash" + ], + "h1": [], + "cards": [], + "pagination_links": [], + "breadcrumbs": [], + "image_count": 3, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/robots.txt", + "status": 200, + "rules": [ + "User-agent: *", + "Allow: /", + "Disallow: /admin/", + "Disallow: /api/", + "Disallow: /storage/", + "Disallow: /vendor/", + "Disallow: /test/", + "Disallow: /*?*", + "", + "Sitemap: http://127.0.0.1:8103/sitemap.xml" + ] + }, + { + "path": "/sitemap.xml", + "status": 200 + }, + { + "path": "/a/fn20261021.html", + "status": 200, + "title": "「10月21日」2026年最新高速SSR/V2ray/Clash/Shadowrocket免费节点订阅链接 - 免费节点", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/a/fn20261021.html" + ], + "h1": [ + "「10月21日」2026年最新高速SSR/V2ray/Clash/Shadowrocket免费节点订阅链接" + ], + "cards": [], + "pagination_links": [], + "breadcrumbs": [ + { + "href": "/", + "resolved": "/" + }, + { + "href": "freenode", + "resolved": "/a/freenode" + } + ], + "image_count": 4, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/a/fn20260910.html", + "status": 200, + "title": "「9月10日」2026年最新高速SSR/V2ray/Clash/Shadowrocket免费节点订阅链接 - 免费节点", + "robots": "noindex, follow", + "canonical": [ + "http://127.0.0.1:8103/a/fn20260910.html" + ], + "h1": [ + "「9月10日」2026年最新高速SSR/V2ray/Clash/Shadowrocket免费节点订阅链接" + ], + "cards": [], + "pagination_links": [], + "breadcrumbs": [ + { + "href": "/", + "resolved": "/" + }, + { + "href": "freenode", + "resolved": "/a/freenode" + } + ], + "image_count": 4, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + }, + { + "path": "/a/m167.html", + "status": 200, + "title": "「Clash for Windows」Windows、Mac、Linux,桌面系统全支持 - Windows", + "robots": "index, follow", + "canonical": [ + "http://127.0.0.1:8103/a/m167.html" + ], + "h1": [ + "「Clash for Windows」Windows、Mac、Linux,桌面系统全支持" + ], + "cards": [], + "pagination_links": [], + "breadcrumbs": [ + { + "href": "/", + "resolved": "/" + }, + { + "href": "client", + "resolved": "/a/client" + }, + { + "href": "windows", + "resolved": "/a/windows" + } + ], + "image_count": 4, + "images_missing_dimensions": 2, + "images_missing_alt": 0 + } + ], + "sitemap_paths": [ + "/", + "/a/fn20261021.html", + "/a/ssi20261021.html", + "/a/fn20261020.html", + "/a/ssi20261020.html", + "/a/fn20261019.html", + "/a/ssi20261019.html", + "/a/fn20261018.html", + "/a/ssi20261018.html", + "/a/fn20261017.html", + "/a/ssi20261017.html", + "/a/fn20261016.html", + "/a/ssi20261016.html", + "/a/m167.html", + "/a/m174.html", + "/a/m173.html", + "/a/m172.html", + "/a/m171.html", + "/a/m170.html", + "/a/m169.html" + ], + "html_exact_duplicate_groups": [ + [ + "ssi20260922", + "ssi20260907", + "ssi20260906" + ], + [ + "ssi20260909", + "ssi20260908" + ], + [ + "ssi20260827", + "ssi20260826", + "ssi20260825", + "ssi20260824" + ], + [ + "ssi20260823", + "ssi20260822" + ], + [ + "m174", + "m173" + ] + ], + "content_metrics": { + "descriptions_with_html": 78, + "zero_node_description_count": 4, + "indexable_zero_node_slugs": [ + "fn20261021", + "fn20261020", + "fn20261019" + ], + "guides": [ + { + "slug": "m167", + "content_chars": 170 + }, + { + "slug": "m174", + "content_chars": 176 + }, + { + "slug": "m173", + "content_chars": 176 + }, + { + "slug": "m172", + "content_chars": 227 + }, + { + "slug": "m171", + "content_chars": 138 + }, + { + "slug": "m170", + "content_chars": 258 + }, + { + "slug": "m169", + "content_chars": 355 + } + ], + "body_promotional_links_without_rel": 160, + "articles_pending_automatic_likes": 7 + }, + "search_status": [ + { + "path": "/health", + "status": 200, + "health": "available", + "documents": null, + "isIndexing": null, + "estimatedTotalHits": null, + "error_code": null + }, + { + "path": "/indexes/articles/stats", + "status": 200, + "health": null, + "documents": 40, + "isIndexing": false, + "estimatedTotalHits": null, + "error_code": null + }, + { + "path": "/indexes/articles/search?q=Clash&limit=0", + "status": 200, + "health": null, + "documents": null, + "isIndexing": null, + "estimatedTotalHits": 7, + "error_code": null + }, + { + "path": "/indexes/articles/search?q=Clash&limit=0&sort=iIsTop:desc", + "status": 200, + "health": null, + "documents": null, + "isIndexing": null, + "estimatedTotalHits": 7, + "error_code": null + } + ], + "search_id_match": { + "status": 200, + "returned_hits": 7, + "ids_present_in_fna": 0, + "same_id_and_slug": 0 + }, + "browser_checks": [ + { + "path": "/", + "javascript": true, + "width": 390, + "status": 200, + "overflow": false, + "page_errors": [], + "initial_cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "after_load": null, + "blocked_hosts": [ + "umami.gemcook.net", + "resource.gemcook.net" + ] + }, + { + "path": "/?page=2", + "javascript": true, + "width": 1280, + "status": 200, + "overflow": false, + "page_errors": [], + "initial_cards": [ + "/a/fn20261019.html", + "/a/fn20261018.html" + ], + "after_load": { + "cards": [ + "/a/fn20261019.html", + "/a/fn20261018.html", + "/a/fn20261019.html", + "/a/fn20261018.html" + ], + "loadCount": 1 + }, + "blocked_hosts": [ + "umami.gemcook.net", + "resource.gemcook.net" + ] + }, + { + "path": "/client/windows", + "javascript": true, + "width": 390, + "status": 200, + "overflow": false, + "page_errors": [], + "initial_cards": [ + "/a/m167.html" + ], + "after_load": null, + "blocked_hosts": [ + "umami.gemcook.net", + "resource.gemcook.net" + ] + }, + { + "path": "/a/m167.html", + "javascript": true, + "width": 390, + "status": 200, + "overflow": false, + "page_errors": [], + "initial_cards": [], + "after_load": null, + "blocked_hosts": [ + "umami.gemcook.net" + ] + }, + { + "path": "/", + "javascript": false, + "width": 390, + "status": 200, + "overflow": false, + "page_errors": [], + "initial_cards": [ + "/a/fn20261021.html", + "/a/fn20261020.html" + ], + "after_load": null, + "blocked_hosts": [ + "resource.gemcook.net" + ] + } + ], + "mobile_320_checks": [ + { + "path": "/", + "overflow": false, + "menu": { + "left": 0, + "right": 256, + "links": 8 + } + }, + { + "path": "/client/windows", + "overflow": false + }, + { + "path": "/a/m167.html", + "overflow": false + } + ], + "delivery_verification": { + "implementation_items": 36, + "acceptance_scenarios": 20, + "website_source_asset_environment_files_unchanged": 195, + "article_category_tag_audit_fields_unchanged": true, + "local_document_links_valid": true, + "gemdocs_check": "PASS", + "code_modified": false, + "business_data_modified": false, + "committed": false, + "pushed": false, + "deployed": false + } +} diff --git a/docs/maintenance/SEO_PLAN.md b/docs/maintenance/SEO_PLAN.md new file mode 100644 index 00000000..353d8c40 --- /dev/null +++ b/docs/maintenance/SEO_PLAN.md @@ -0,0 +1,734 @@ +# FNA_V3 SEO 优化建议与执行清单 + +评估日期:2026-10-22,Asia/Shanghai。状态:**分析与建议文档已完成;SEO-001 的部署定位已由用户确认,配置改造尚未实施;SEO-020 于2026-10-27完成本地教程正文更新,设备实测及生产验收未做,D02首页最新免费节点全文展示于2026-10-27本地完成,其余项目尚未实施**。本文件是后续 SEO 工作的唯一执行清单;按 `SEO-001` 至 `SEO-036` 跟踪,实施后在本文件更新结果,不另建重复的“最新版计划”。 + +本轮依据当前代码、当前本地数据库、重新取得的 HTTP 响应及受限浏览器检查形成结论。网站源码、样式和业务数据未作修改。当前三款 DPL 广告属于已存在的实现,纳入分析基准并保留。网站仍在独立本地副本中开发;用户随后确认未来替换现有 cfn,并支持同一套代码部署多个同类站点,ClashFreeNode 为主力站,尚未实际部署或迁移。 + +**最优先的工作是让有价值的内容拥有唯一、稳定、可发现的地址,并让页面真实兑现搜索结果中的承诺。** 当前主要问题集中于重复 URL、分页发现路径、内容生命周期和资源质量;仅增加标题、关键词或结构化数据不能解决这些问题。现有 Laravel Blade 已能在首次 HTML 响应中输出文章正文,没有证据表明必须改用另一套框架或全面重写网站。 + +## 1 如何阅读和执行 + +- 先看第 2 节的结论与证据,再确定第 3 节的产品决策。 +- 第 4 节定义目标 URL 和索引规则;这是实现之间保持一致的依据。 +- 第 5 节是总清单,第 6 节给出每一项的具体范围和验收条件。 +- 第 7 节规定实施批次,第 8 节是验收矩阵,第 9 节规定发布后的效果观察方法。 +- 每项实现都要记录:实际改动、代码验证、本地页面验证、是否发布、线上验证范围。不能把“代码完成”写成“Google 已收录”。 + +优先级含义: + +| 级别 | 含义 | +| --- | --- | +| P0 | 基础规则冲突,或公开发布前必须解决的风险。标注“发布前”的项目不意味着本地正在发生线上事故 | +| P1 | 影响主题识别、内容价值、内链、索引一致性或长期维护的主要优化 | +| P2 | 在基础和内容就绪后改善展示、体验、效率及分发 | + +证据等级:**已确认**指本轮代码、数据或响应直接支持;**条件性风险**指相关代码存在,但触发条件或生产影响未确认;**策略建议**指需要结合业务取舍决定;**待线上验证**指必须有实际生产环境或搜索平台数据才能判断。 + +本报告以 Google 的技术要求为主要参照;通用的 URL、HTTP、内容与内链原则也有助于其他搜索引擎。Bing、百度等渠道的具体投入,应由目标用户和后续数据决定,不能假定它们完全采用相同的收录规则。 + +## 2 当前状态和核心判断 + +### 2.1 检查范围 + +| 项目 | 本轮范围与结果 | +| --- | --- | +| 代码 | 当前工作目录 `/Users/hellcat/Documents/GemCodes/FNA_V3`,包含原有并行修改及广告实现 | +| 数据 | 本机 `fna_v3`,167 篇文章、8 个分类、25 个标签;业务数据只读 | +| HTTP | 230 个不同的本地地址,覆盖全部文章、全部标签、分类和代表性异常参数;227 个 200、3 个预期 404 | +| 文章索引声明 | 19 篇 `index, follow`,148 篇 `noindex, follow`;这是页面声明,**不是 Google 实际收录数量** | +| Sitemap | 20 个 URL:主页加 19 篇文章;本轮与文章 noindex 声明无冲突,未包含分类或标签 | +| 浏览器 | 5 组桌面/手机/禁用 JS 检查,另补 3 组 320px 检查;所有非本地网络请求被阻止 | +| 资源和搜索 | 本地 Meilisearch 的只读状态和 ID 对照;未下载在线订阅、未检测节点、未请求线上图片或统计脚本 | +| 线上证据 | 未读取 Search Console、线上抓取日志、真实访问指标、外链或关键词排名,不能据此给出排名或流量损失数值 | + +数据采样时应用使用 UTC,数据库 `NOW()` 使用 UTC+8:分别约为 `2026-10-22 05:10 UTC` 和 `2026-10-22 13:10`。计数受时间及后续数据变化影响;实施时应重新计算,不把 19 或 20 写死为测试长期期望值。 + +### 2.2 当前值得保留的基础 + +1. **首次响应已有内容。** 禁用 JavaScript 后,首页的首批文章仍能显示;文章标题与正文由服务端输出。应在现有渲染方式上补足链接和元数据。 +2. **真正不存在的对象返回 404。** 本轮不存在的文章、分类和标签均返回 404;问题主要是合法分类的错误前缀、分页和搜索边界。 +3. **文章页有明确 H1,基础语言与 viewport 已设置。** 不需要把全部页面基础能力推倒重做。 +4. **已有 robots、canonical、sitemap 和按内容年龄控制索引的机制。** 重点是修正它们之间的规则,不是简单从零叠加另一套。 +5. **DPL 广告已有可见“广告”标识,链接带 `sponsored noopener noreferrer`。** 装饰性标志使用空 alt,且已指定宽高,这是合理做法。 +6. **本轮受限检查中 320px/390px 代表页面无横向溢出,手机菜单动画完成后正常展开。** 这只是本地样本验收,不能替代线上性能、完整无障碍或所有设备验证。 + +### 2.3 主要证据 + +| 证据 | 本轮发现 | 意义及边界 | 对应项目 | +| --- | --- | --- | --- | +| E01 | `/`、`/freenode`、`/wrong/freenode` 返回相同列表,各自声明 canonical;`/windows`、`/client/windows`、`/wrong/windows` 也重复 | 路由没有验证父分类。错误路径可扩张出大量有效副本;不能据此声称已遭搜索处罚 | 004、009 | +| E02 | 所有检查到的列表均无普通分页 ``;robots 屏蔽所有带 `?` 的 URL;第 2 页 canonical 指向第一页 | 内容发现链路与规范化信号同时有缺口 | 005、006 | +| E03 | 从首页沿本轮页面中的实际 HTML 站内链接遍历,只能到达 12 篇文章;19 篇允许索引的文章中有 7 篇未能沿该图到达 | 未把 sitemap、JS 滚动或外链算作 HTML 内链。不是断言搜索引擎绝不可能发现它们 | 005、014 | +| E04 | 浏览器直接进入 `/?page=2` 后加载下一批,重复追加了第 2 页两篇文章 | JS 以 `loadCount + 2` 计算页号,没有从当前 URL 初始化 | 005 | +| E05 | `/?page=40`、`/?page=99` 空列表仍为 200/index;`page=0`、负数、字符串回到首页内容 | 无效分页和空结果的响应策略需明确。合法空搜索并不必须返回 404 | 007 | +| E06 | 首页、各分类、标签、搜索均使用同一站点标题和简介;主页、父分类、标签、搜索缺少内容 H1;Windows 分类 H1 为 `windows1` | 不同搜索意图没有得到清楚描述;单独缺 H1 不等于排名惩罚 | 010、011 | +| E07 | 78 篇文章副标题含 HTML;公共布局在所有 meta description 前附加请求当天日期 | 老文章被描述成“今天”的内容,HTML 标签成为摘要字符串的一部分 | 011、012 | +| E08 | 文章面包屑相对链接 `client` 在文章地址下解析为 `/a/client`;该地址又被宽松分类路由接受 | 错误内链进一步制造副本 | 009 | +| E09 | 167 篇文章全部发布;分类列表缺少文章状态过滤,文章详情缺少分类状态过滤 | 当前没有草稿,因此未证实已有草稿泄露;未来发布控制边界不一致 | 008 | +| E10 | 78 篇节点文章、82 篇账号文章使用 7 天 noindex;清理命令还定义了 180 天删除 | 这是产品策略,不能直接判错;需要按长期价值与资源有效期决定 | 003、018 | +| E11 | 原始正文 HTML 完全相同的 5 组共 13 篇,包括两个客户端页面;7 篇客户端正文可见文本约 138–355 字 | 重复已经确认;字数只用于描述内容规模,没有最低字数达标线 | 019、020 | +| E12 | 最新连续三篇 `fn20261019`、`fn20261020`、`fn20261021` 的正文及副标题均为 0 个可用节点,标题仍称最新高速免费节点;全库共有 4 篇零节点记录 | 无法仅凭文章判断远端订阅此刻是否真为空;已确认的是发布内容与承诺需要复核 | 017、018 | +| E13 | 本地 `articles` 搜索索引仅 40 条;Clash 命中 7 条,其 ID 在当前 167 篇文章中全部不存在;页面显示空结果 | 当前应用与搜索索引不匹配。索引实际归属未进一步调查,不得直接清空这个共享名称的索引 | 016 | +| E14 | `updated_at` 被点赞增减和分类关联更新使用,sitemap 却把它作为 lastmod;存在自动注入点赞逻辑,7 篇还有待注入计数 | 内容日期与互动数据耦合;未启动本地调度,也未确认线上任务当前是否运行 | 012、022、029 | +| E15 | 全部文章未输出 JSON-LD;当前响应中的图片均有 alt 属性,两个导航 logo 未带宽高;列表封面使用 CSS 背景 | 结构化数据是后续增强;不能把装饰图空 alt 当缺陷,也不能把缺宽高直接等同实测 CLS 不合格 | 024、026 | +| E16 | 文章“复制链接”模板写入站点首页;页面品牌文本为 `v2rayfreenode`,样式/标志使用 cfn/Clash;通用 OG 图为相对地址 | 分享链接存在功能错误;站点身份需统一,但 FNA_V3 内部代号不必作为公开品牌 | 001、025 | +| E17 | 新 DPL 组件链接已带 sponsored;160 篇资源正文中的 `fuuu.cloud` 链接未带 rel 属性 | 原有正文推广和新广告组件需要分别治理;不能把新广告已经正确理解为所有推广均处理完毕 | 023 | +| E18 | 当前整页缓存关闭;默认配置若启用会缓存 7 天,文章事件仅尝试失效首页 | 当前不是“正在缓存错误内容”的故障;启用前存在过期、撤稿及多入口失效风险 | 029 | +| E19 | 三个文章接收接口在运行时路由表中只有 web 中间件,`api/*` 排除 CSRF;接收逻辑自动发布并可能调用推送、通知和资源服务 | 应用层缺少已挂载的入站认证,是公开部署前风险。未发送写入请求,未核实生产边缘访问控制 | 030、032 | + +### 2.4 关键因果关系 + +当前链路是: + +```text +内容按天生成 → 标题与正文高度模板化 → 新文章仅有短暂索引窗口 + ↓ +每页只展示 2 条 → 后续页依赖滚动 → 普通链接难以到达较深文章 + ↓ +分页被 robots 屏蔽,canonical 又指回第一页 + ↓ +发现与积累主要依赖 sitemap 和每日新 URL,长期内容资产较弱 +``` + +这里的判断是技术与内容策略推断,不是对线上 Google 抓取行为的实测描述。167 篇的规模本身不值得优先做复杂“抓取预算”工程;应先消除无限别名、无效分页和低价值重复。 + +## 3 实施前需要确定的产品决策 + +D01、D02 已由用户确认;其余条目仍是建议,未因这些确认而自动获批。 + +| 决策 | 方案与确认状态 | 为什么 | 影响范围 | +| --- | --- | --- | --- | +| D01 上线身份 | 用户已确认:未来替换现有 cfn;同一套代码支持多个同类站点;ClashFreeNode 是主力站,本地继续独立 | 代码共用,实例身份分别配置;主力站升级需要保护现有有效地址,其他站点不能误用其域名和统计 | 001、021、031、032、036 | +| D02 首页和免费节点页 | 2026-10-27用户明确:首页直接展示日期最新的一篇免费节点文章全文;`/freenode` 保留历史列表。本地已实施,不要求文章必须是当天 | 首页与栏目承担不同展示职能;首页和对应详情的规范地址、索引策略仍在004/018中处理,不把本次功能修改视作SEO全项完成 | 004、010、018 | +| D03 日更文章的角色 | 稳定资源入口承接“当前可用”的需求;有独立记录价值的日更页保留,重复或失败记录不争取搜索曝光 | 用户需要可用资源,日期变动本身不是新价值 | 003、017、018 | +| D04 历史内容 | 先按有效性、独立信息、已有流量/外链分类,再决定 index、noindex、合并或删除 | 不批量把 148 篇开放收录,也不机械全删/全跳首页 | 003、018、036 | +| D05 标签 | 只培养有独立意图、有可维护内容的标签页;其余可保留浏览功能并 noindex | 25 个标签中存在同义名称和高度重叠文章集合 | 015 | +| D06 渠道和目标 | 首先定义有效自然访问和实际使用完成率,Google 为初始技术基线;其他渠道按目标市场补充 | 没有搜索量和 Search Console 数据时不能编造关键词机会或流量预测 | 002、035 | +| D07 样式边界 | 保持既有视觉语言和已批准广告方案;标题语义、链接、数据真实性先行;新增可见信息或调整广告占比单独评审 | SEO 改动不默认授权重设计整站或移除已批准广告 | 010、023、027 | + +D01 的部署角色已明确。具体生产映射、新增实例清单以及多站相同内容的收录归属仍需在相应实施项确定;不阻塞本地分页、URL 规则和元数据开发。用户尚未授权本次上线或修改现有 cfn。 + +## 4 建议采用的 URL 与索引规则 + +### 4.1 页面行为矩阵 + +下表为建议合同,实施前与 D02–D05 一起确认。 + +| 页面类型 | 建议 HTTP | 抓取与索引 | Canonical | Sitemap | +| --- | --- | --- | --- | --- | +| 正式首页/稳定资源入口 | 200 | 可抓取,内容有效时 index | 唯一正式地址 | 是 | +| 有独立价值的分类首页 | 200 | 可抓取,index | 当前规范地址 | 是 | +| 合法第 2 页及以后 | 200 | 可抓取,默认可 index | 含正确 `page=N` 的本页地址 | 一般依赖顺序内链,不强求列入 | +| `page=1` | 301 | 收敛到无 page 的第一页 | 目标页输出 | 否 | +| 已知历史分类别名 | 301 | 一跳到等价目标,保留有效页码 | 目标页输出 | 否 | +| 错误父分类、未知 slug | 404 | 不提供可索引替代正文 | 不指向无关首页 | 否 | +| 页码越界/格式无效 | 404,或对明确等价输入做受控 301 | 不返回通用首页 200 | 不伪称与首页等价 | 否 | +| 完整、已发布文章 | 200 | 按内容策略 index | 自身稳定 URL | index 时加入 | +| 有保留价值但不面向搜索的旧记录 | 200 | 可抓取,noindex | 自身地址;不同时强行指定另一 canonical 来表达不同目的 | 否 | +| 已合并且目标真正等价的旧文章 | 301 | 到已选定的主文章 | 目标页输出 | 否 | +| 已删除且无替代内容 | 404 或明确 410 | 不索引 | 不批量跳首页 | 否 | +| 有实际主题价值的标签 | 200 | 可抓取,index | 自身规范地址 | 按维护策略加入 | +| 普通低价值标签/站内搜索 | 200 | 可抓取,noindex | 自身干净地址或不输出,保持统一规则 | 否 | +| 有效搜索词但无匹配 | 200 | noindex,显示真实无结果状态 | 同上 | 否 | +| 搜索服务故障 | 合适的 5xx 或明确降级状态 | 不伪装成“没有内容” | 不作为正常搜索页参与索引 | 否 | +| 草稿/未到发布时间/不可公开对象 | 匿名 404 或访问受控 | 不进入公开列表、搜索和 sitemap | 不公开输出 | 否 | +| 运维、API、测试、点赞等接口 | 按接口协议 | 不作为内容页面发现和索引;访问控制另行实现 | 不输出文章 canonical | 否 | + +`robots.txt` 控制抓取,`noindex` 控制索引,canonical 表达代表性 URL,这三者各有用途。需要让搜索引擎读取 noindex 时,不能同时以 robots 禁止其访问该页面。[Google noindex 说明](https://developers.google.com/search/docs/crawling-indexing/block-indexing) + +### 4.2 参数和路径规则 + +- `page` 是会改变内容的参数,应保留在分页 canonical 中;`utm_*` 等跟踪参数通常不改变正文,应从 canonical 去掉。 +- 查询参数要按明确白名单处理。不要为了排除跟踪参数而一并删除页码,也不要放任任意参数生成自指 canonical。 +- 分类 URL 由真实分类关系生成;不能只取路径最后一段就当有效分类。 +- 文章继续保留 `/a/{slug}.html`,没有必要为“URL 看起来更 SEO”大规模更换。标签的随机后缀也不是必须去掉的错误。 +- `Andorid` 应纠正可见名称。若同时把现有 `andorid` slug 改成 `android`,必须安排旧地址映射;名称修正和 URL 迁移应分开验收。 +- 全站使用同一个 URL 生成入口,供导航、文章卡片、面包屑、canonical、OG、sitemap 和推送共同使用。 + +重定向、canonical 和 sitemap 应指向同一主地址;canonical 是规范化信号,不是保证搜索引擎一定采纳的命令。[Google 规范化说明](https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls) + +### 4.3 内容模型的最小改造方向 + +不需要先建一套大型 CMS。先区分下列概念,能用明确的服务或计算属性表达的,不必全部新增数据库字段: + +| 概念 | 作用 | 当前对应及缺口 | +| --- | --- | --- | +| 可公开访问 | 发布状态、分类状态、发布时间共同决定 | 当前各查询判断不一致 | +| 可索引 | 在可公开基础上,再考虑质量、过期、重复、明确编辑选择 | 当前主要依赖分类 noindexday | +| 规范 URL | 每个实体唯一地址和有限历史别名 | 当前多处拼接,未验证父路径 | +| 首次发布时间 | 表达首次公开时间 | 不直接把导入时间当原创发布时间 | +| 实质内容更新时间 | 影响可见更新日期、schema、sitemap | 不能继续无条件使用互动也会修改的 updated_at | +| 最后验证时间与状态 | 描述资源/教程的最近实际核验 | 与发布时间、修改时间分开;未知状态不假装已验证 | +| SEO 标题与简介 | 允许重要页面有编辑覆盖,缺省时从内容生成 | 当前列表全局模板,文章副标题混有展示 HTML | +| 来源和内容类型 | 区分资源快照、长期教程、分发内容、原创评测 | 为索引策略和内容模板提供依据 | + +“公开”“索引”“资源有效”是三种不同状态。noindex 不能代替权限控制;资源失败也不应自动等同于整篇教程应被删除。 + +## 5 执行总表 + +所有项目当前均未实施。依赖列用于确定顺序,不是要求一次性同时完成全部项目。 + +| 完成 | 编号 | 项目 | 优先级 | 主要依赖 | 当前性质 | +| --- | --- | --- | --- | --- | --- | +| [ ] | SEO-001 | 明确公开身份、主域名和环境边界 | P0 发布前 | D01 | 部署定位已确认,配置待实施 | +| [ ] | SEO-002 | 确定搜索意图、目标用户和效果基线 | P1 | D06 | 待决策/待数据 | +| [ ] | SEO-003 | 确定内容生命周期与索引资格 | P0 策略 | D03、D04 | 待决策 | +| [ ] | SEO-004 | 统一规范 URL 和历史别名 | P0 | D02 | 已确认 | +| [ ] | SEO-005 | 修复分页发现与滚动加载 | P0 | 004 | 已确认 | +| [ ] | SEO-006 | 协调 robots、参数和 noindex | P0 | 003、005 | 已确认 | +| [ ] | SEO-007 | 修复无效分页、空结果与错误状态 | P0 | 004、005 | 已确认 | +| [ ] | SEO-008 | 统一公开可见性与发布时间判断 | P0 发布前 | 003 | 条件性风险 | +| [ ] | SEO-009 | 修复面包屑和全站内链地址 | P1 | 004 | 已确认 | +| [ ] | SEO-010 | 分类、标签、搜索的标题与语义层级 | P1 | 001、004 | 已确认 | +| [ ] | SEO-011 | 生成真实、干净的页面简介 | P1 | 010 | 已确认 | +| [ ] | SEO-012 | 分离真实内容日期并统一时间基准 | P1 | 003 | 已确认/条件性风险 | +| [ ] | SEO-013 | 统一 sitemap 的集合和 lastmod | P1 | 003、004、008、012 | 已确认 | +| [ ] | SEO-014 | 建立长期内链和内容导航 | P1 | 005、009、018 | 已确认/策略建议 | +| [ ] | SEO-015 | 整理标签与重复主题页 | P1 | 002、003 | 策略建议 | +| [ ] | SEO-016 | 隔离并同步本站搜索索引 | P1 | 008、032 | 已确认 | +| [ ] | SEO-017 | 建立空资源与检测失败的发布门槛 | P0 内容 | 003 | 已确认/待上游核实 | +| [ ] | SEO-018 | 建立稳定资源入口和日更归档策略 | P1 | 002、003、004、017 | 策略建议 | +| [~] | SEO-019 | 处理真实重复文章与跨平台内容(本地Mac/Linux教程已区分) | P1 | 003、004 | 已确认 | +| [~] | SEO-020 | 提升客户端教程的任务完成能力(本地全栏目正文完成,实机/生产未验收) | P1 | 002、019 | 已确认/内容建议 | +| [ ] | SEO-021 | 明确来源、验证和跨站内容差异 | P1 | 017、020 | 策略建议 | +| [ ] | SEO-022 | 作者、编辑责任与真实互动数据 | P1 | 001、012 | 已确认/策略建议 | +| [ ] | SEO-023 | 推广链接、广告与正文体验 | P1 | D07 | 部分已具备,仍有缺口 | +| [ ] | SEO-024 | 添加匹配真实内容的结构化数据 | P2 | 009、010、012、022 | 增强项 | +| [ ] | SEO-025 | 修复分享地址和社交预览信息 | P2 | 001、004、011 | 已确认 | +| [ ] | SEO-026 | 图片语义、尺寸和加载方式 | P2 | 020、028 | 已确认/待测量 | +| [ ] | SEO-027 | 手机端与无障碍完整验收 | P2 | 005、010 | 部分样本通过 | +| [ ] | SEO-028 | 建立正式构建性能基线并按瓶颈优化 | P2 | 026、027 | 待测量 | +| [ ] | SEO-029 | 缓存与发布、撤稿、到期一致性 | P1 启用前 | 003、008、012 | 条件性风险 | +| [ ] | SEO-030 | 文章接收、更新与删除的发布合同 | P0 发布前 | 003、008、017、029 | 已确认/条件性风险 | +| [ ] | SEO-031 | 正式主机、HTTPS 与 HTTP 服务质量 | P0 发布前 | 001、004 | 待部署验证 | +| [ ] | SEO-032 | 本地、预发布和生产资源隔离 | P0 发布前 | 001 | 已确认/条件性风险 | +| [ ] | SEO-033 | 规范 IndexNow 及搜索提交 | P2 | 003、004、030、032 | 已确认/待部署验证 | +| [ ] | SEO-034 | SEO 自动回归与数据样例 | P1 | 跟随各批次 | 当前测试缺口 | +| [ ] | SEO-035 | 搜索平台与业务效果监测 | P1 上线后 | 001、002、036 | 待线上数据 | +| [ ] | SEO-036 | 发布、迁移、回滚与复核 | P0 发布时 | 前述必需项 | 待发布授权 | + +## 6 各项优化的实施说明 + +### SEO-001 明确公开身份、主域名和环境边界 + +**优先级:P0,正式发布前。** 当前 FNA_V3 是内部项目名,界面标志体现 Clash FreeNode,`app.name` 却是 `v2rayfreenode`,底层站点代码为 cfn。根环境文件保留 `fn-b.loc`,本轮 PHP 服务用启动参数将实际 APP_URL 设为本地 8103,因此本轮页面并没有错误指向旧域名。 + +建议明确公开品牌、正式主机、是否接替 cfn,以及各环境允许生成的 URL。品牌名称、首页标题、logo alt、作者/发布者、WebSite 数据、分享卡片与统计应使用一致配置。不要把“FNA_V3”自动展示成用户品牌,也不要仅因本地克隆而对原站做跨域 canonical。 + +**实施范围:** 站点配置、公共布局、环境部署检查;生产域名最终确定后再完成真实映射。 + +**验收:** 本地只生成本地内容 URL;预发布具有明确防索引措施;生产只生成获准主域 URL;页面身份不再同时混用互不一致的站名。替站或新站的决定记录在 D01。 + +**用户已确认的方向:** FNA_V3 以后替换现有 cfn;同一套代码可能部署多个同类网站;ClashFreeNode 是主力站。FNA_V3 继续作为内部项目名,不据此更改其他网站的公开品牌。 + +**据此收敛的实施方案:** 共用代码,以每个部署实例的配置提供站点标识、公开名称、主域、标题与简介、logo、发布者、统计和搜索提交身份;不要把 ClashFreeNode 的域名和品牌写死到所有部署。各实例的数据、搜索、缓存、会话及外部发送边界在 SEO-032 核实。ClashFreeNode 的有效旧文章地址优先保留,真正需要变更的地址才建立逐条迁移映射。 + +多个站点的内容相同与否、是否各自争取独立收录,以及是否有副本归集到主力站,在 SEO-021 明确;“主力站”不自动授权把所有副站 canonical 指向它,也不代表复制内容的各站一定能获得独立搜索曝光。 + +**当前状态:部署定位与主力品牌已确认,配置统一和环境验收尚未实施;未修改代码,未部署。** + +### SEO-002 确定搜索意图、目标用户和效果基线 + +**优先级:P1。** 当前站点混合“今天找可用资源”“选择客户端”“查安装使用方法”“获取账号资源”四类需求。它们不应都用一段“免费节点每天更新”的文案承接。 + +先建立意图到页面的映射:即时资源由稳定入口承接,软件选型由客户端分类承接,具体操作由教程承接,日更历史由归档承接。关键词应从真实用户用语、站内搜索和获得授权后的搜索平台数据提炼,不预设“某词一定有高搜索量”。中文简体是当前内容语言;没有多语言版本时不添加虚假的 hreflang。 + +**实施范围:** 内容规划、指标定义,后续关联 SEO-035。 + +**验收:** 每类目标页面能回答“谁搜什么、进来要完成什么、本站有什么独立帮助”。指标至少包含非品牌自然点击、合格页面收录状况,以及不含秘密的实际资源使用事件。没有流量数据的字段保持待采集。 + +### SEO-003 确定内容生命周期与索引资格 + +**优先级:P0 策略前置。** 160 篇资源类文章采用 7 天 noindex,另有 180 天删除命令;这些规则与长期教程应分开。当前 148 篇不索引并不能证明策略错误,也不能证明其余 19 篇都是值得排名的页面。 + +建议将“可公开”“可索引”“已验证可用”“仅供历史记录”拆开判断。资源检测失败、真实检测为零、已过期、正文重复、仍有独立知识价值,应有不同处理。生命周期规则由一个入口计算,供详情、列表、搜索、sitemap、缓存与推送共同调用。 + +**实施范围:** 内容策略与发布资格服务;只有确认缺少必要信息时再增字段。 + +**验收:** 对新发布、过期、失败、永久教程、隐藏分类、未来发布和合并内容各有明确行为。时间边界冻结测试覆盖到期前后。先记录策略理由,再处理历史数据;不因想增加 URL 数量而批量解除 noindex。 + +### SEO-004 统一规范 URL 和历史别名 + +**优先级:P0。证据:E01。** 当前控制器只取第二段或第一段 slug,未核实路径关系,导致 `/wrong/windows` 也能成为 Windows 分类页。布局再用 `url()->current()` 为每个副本生成 canonical。 + +建立唯一 URL 生成方法和受控别名表。正式分类路径要么统一平级,要么统一真实父子路径;本项目导航已经使用 `/client/windows`,因此建议沿用该层级,并将真正已使用的平级旧入口映射过去。错误任意前缀返回 404。主页与 freenode 根据 D02 选择,避免循环跳转。不要为无效前缀批量建立重定向规则。 + +**实施范围:** 路由、Web 控制器、URL 生成方法、布局及后续调用方。 + +**验收:** `/wrong/windows`、`/wrong/freenode` 为 404;已认可别名一跳到唯一 200 目标;所有内链与 canonical 一致;跟踪参数不产生新主地址;必要分页参数在跳转后仍指向对应内容。旧文章 `/a/...html` 保持稳定。 + +### SEO-005 修复分页发现与滚动加载 + +**优先级:P0。证据:E02–E04。** 当前每页 2 条,78 篇节点文章形成 39 页;HTML 中没有下一页链接。直接进入第 2 页再加载,当前浏览器已复现重复内容。 + +保留滚动加载作为交互增强,同时服务端输出普通的下一页、上一页及适当的分页导航。第 N 页必须可独立打开,canonical 保留正确页码。JS 从当前页或服务端下一页链接初始化,最后一页明确停止;验证置顶和相同创建时间下的排序稳定性,必要时追加 id 排序。数据不断新增时也要定义跨页重复的容忍或去重规则。 + +每页条数建议先以 **10–20 条作为项目试验区间**,结合页面重量和可读性决定;这不是搜索引擎规定的数值。可以保持现有卡片视觉样式。 + +**实施范围:** 文章查询、列表模板、分页组件、滚动 JS。 + +**验收:** 无 JS 时可从首页沿链接到达所有应公开浏览的记录;第 2 页继续加载取得第 3 页;末页停止;刷新与后退后内容页码一致;所有有效分页自指 canonical。 + +Google 明确建议顺序可抓取链接、独立分页 URL 和分页自身 canonical;同一分页序列允许使用相同标题与简介,不必为此制造不同文案。[Google 分页指南](https://developers.google.com/search/docs/specialty/ecommerce/pagination-and-incremental-page-loading) + +### SEO-006 协调 robots、参数和 noindex + +**优先级:P0。证据:E02。** `Disallow: /*?*` 同时拦住有效分页和跟踪参数。只改 canonical 或只加分页按钮都会留下规则冲突。 + +按参数语义制定策略:合法 page 可抓取;跟踪参数归一;不需要搜索曝光的站内搜索及低价值集合用 noindex。保留真实私有/非内容路径的抓取限制,但不能把 robots 当认证。`/storage/` 是否可屏蔽,应先核实是否承载公开文章图片;当前外部资源主机的 robots 需要在部署阶段分别核实。 + +**实施范围:** RobotsController、页面索引策略、参数规范化。 + +**验收:** 测试 `?page=2`、`?page=2&utm_source=x`、搜索地址、静态 CSS/JS/图片和非内容接口;确认 crawler 能读取需要生效的 noindex,且关键渲染资产不被误封。与 SEO-005 同一批验收,不留下临时相互冲突状态。 + +### SEO-007 修复无效分页、空结果与错误状态 + +**优先级:P0。证据:E05。** 当前超出末页仍给出“没有任何东西”的 200 页面,容易形成低信息量 URL 和 soft 404 风险;是否已被 Google 判为 soft 404 未知。 + +明确:超界页码应返回 404;非法数字格式使用严格校验;`page=1` 可规范跳转至第一页。合法的站内搜索无结果应保持正常搜索语义和 noindex,而非一律 404。分类真的为空时,依据其是否提供独立介绍决定保留有价值的 200 页还是停止公开。服务故障不能伪装成成功空列表。 + +**验收:** `page=0/-1/abc/极大值` 有确定行为;正常末页仍 200;下一页明确结束;三个不存在对象继续 404;错误模板不包含会误导搜索引擎的正文 canonical。临时维护采用合适的 503,而非把维护提示返回 200。[Google HTTP 状态说明](https://developers.google.com/crawling/docs/troubleshooting/http-status-codes) + +### SEO-008 统一公开可见性与发布时间判断 + +**优先级:P0,公开发布前。证据:E09。** 分类列表没有筛选 `iStatus=1`;标签筛选文章状态但未完整检查分类;详情也未排除不可公开分类。当前样本没有草稿,不应报告成已发生泄露。 + +建立统一公开查询条件:文章已发布、达到公开时间、所属分类及必要父分类可见。详情、分类、标签、搜索、推荐、sitemap 都复用。索引资格在公开资格之上计算;noindex 内容仍可在业务允许的公开列表中浏览,不要误当隐藏。 + +**实施范围:** 文章查询 scope/策略、搜索索引筛选、推荐集合。 + +**验收:** 在独立测试数据库放置发布、草稿、未来文章、隐藏子分类、隐藏父分类五类数据;逐个入口验证。不能通过向当前线上导入库插入测试草稿来验收。 + +### SEO-009 修复面包屑和全站内链地址 + +**优先级:P1。证据:E08。** 文章中的 `href="client"`、`href="windows"` 解析为 `/a/client`、`/a/windows`;文章卡片分类地址又与导航的层级地址不同。 + +面包屑、卡片分类、导航、标签与推荐链接统一调用 SEO-004 的生成方法,使用可解析的根路径或完整绝对 URL。保留清楚的锚文本;修正 `rel"rag"` 的 HTML 拼写,避免把它当成具有 SEO 含义的属性。手机端如继续隐藏视觉面包屑,正文内仍应有可用的所属主题入口。 + +**验收:** 从文章页、分页、标签页打开所有内部导航不再产生 `/a/分类` 或未经认可的父路径;链接不经多跳;锚文本与目标内容一致。后续 BreadcrumbList 使用同一份面包屑数据。 + +### SEO-010 分类、标签、搜索的标题与语义层级 + +**优先级:P1。证据:E06。** 不同类型页面共用站级标题,分类名称和标签主题没有进入页面元信息;Windows 的 H1 用 slug 和当前页数量拼成 `windows1`。 + +建立页面类型模板,同时允许关键页面人工覆盖。建议示意: + +| 页面 | 标题示例,品牌待 D01 确定 | H1 内容 | +| --- | --- | --- | +| 稳定节点入口 | 当前免费节点与订阅使用说明 · 品牌 | 当前免费节点与使用说明 | +| 客户端父分类 | 代理客户端选择与使用指南 · 品牌 | 客户端选择与使用指南 | +| Windows 分类 | Windows 代理客户端与安装指南 · 品牌 | Windows 客户端 | +| 有价值的标签专题 | Clash 使用与订阅排错 · 品牌 | Clash 使用与订阅排错 | +| 搜索 | “Clash”的站内搜索结果 · 品牌 | 搜索结果:Clash | +| 文章 | 准确的文章主题 · 品牌,按需加入有意义的分类 | 文章主题 | + +这些示例是方向,不应在内容尚未具备时直接承诺有完整指南。列表卡片的 `.h5` 类不会自动形成标题语义,可以在保留样式的同时使用合理的 H2/H3。每页推荐一个主要 H1;不把 H1 数量当机械排名公式,也不为不同日期堆砌同一串软件名称。 + +**验收:** 首页、每个分类、标签和搜索各自反映主题;HTML 标题正确转义;页面可见主标题和标题标签一致;没有空标题、调试计数或 slug 代替正式名称。Google 会自行生成展示标题,不能保证逐字采用。[Google 标题说明](https://developers.google.com/search/docs/appearance/title-link) + +### SEO-011 生成真实、干净的页面简介 + +**优先级:P1。证据:E07。** 页面简介和展示副标题应分开:展示文本可以包含强调样式,meta description 应为清洗后的纯文本。当前 78 篇副标题带 HTML,直接进入 description。 + +移除无条件“今天”前缀;按页面主题生成自然摘要,解码实体、去标签、规范空白、正确转义。重要文章允许编辑覆盖,其他页面采用可靠的内容摘要。正文资源数为零或未知时,简介不能继续暗示已提供一批可用资源。搜索页可显示搜索词和结果范围,但仍 noindex。 + +**验收:** 抽查新旧资源、教程、分类和含引号/实体的内容;简介不含 ``、换行碎片或错误日期,与实际内容一致。Google 可能改用正文片段,且没有保证展示完整内容的固定字符上限;不以“必须 160 字符”等规则作为硬验收。[Google 摘要说明](https://developers.google.com/search/docs/appearance/snippet) + +### SEO-012 分离真实内容日期并统一时间基准 + +**优先级:P1。证据:E07、E14。** 当前更新时间混有点赞和分类关联变化;公共模板把当天日期加到老文章摘要;可见相对日期和 sitemap 日期也没有统一的编辑语义。 + +区分首次公开、实质内容更新、最近资源验证和互动变化。先核对导入历史时间的真实时区语义,再确定存储、应用、数据库及展示约定;不能直接把所有历史时间统一加减八小时。索引截止时间应由应用计算后传入查询,或确保数据库与应用同一时基,避免 PHP `now()` 和 SQL `NOW()` 使用不同基准。建议以不可变日期对象计算到期时间。 + +**实施范围:** 日期字段/服务、详情与列表 `` 图可到达全部计划索引页面;关键长期页面以项目目标控制在约 3 次点击内,较深历史归档通过顺序分页可达。此深度是维护目标而非 Google 强制阈值。允许索引页面没有仅靠 sitemap 存在的孤立记录。[Google 链接建议](https://developers.google.com/search/docs/crawling-indexing/links-crawlable) + +### SEO-015 整理标签与重复主题页 + +**优先级:P1。** 当前 25 个标签全部有文章,但“有文章”并不等于值得成为独立搜索落地页。例如“免费苹果账号”“小火箭”“shadowrocket id”“小火箭账号”等各有 82 篇记录;需要比较真实文章集合与意图,不能只按名称合并。 + +将标签分为有独立主题的编辑专题、站内浏览标签、应合并的同义标签。有价值的专题应有清楚简介和精选内容;仅重复列出相同文章的浏览标签可 noindex。对已有流量/外链的标签保留映射。标签后缀随机并不构成必须迁移的 SEO 问题。 + +**验收:** 有一份标签去留决策,记录合并理由和目标地址;站内浏览功能可用;规范化、索引规则与 sitemap 一致;不自动生成大量“客户端 × 日期 × 地区”的近似专题。 + +### SEO-016 隔离并同步本站搜索索引 + +**优先级:P1。证据:E13。** 本轮已核实 Meilisearch 可用,问题并非“服务一定没启动”:索引含 40 条文档,Clash 命中 7 条,但这些 ID 不存在于本库。当前 `Articles::searchableAs()` 固定返回 `articles`,只改数据库名称或仅设置一个未被该方法采用的前缀,不足以保证隔离。 + +给 FNA_V3 分配专属索引名或专属实例,按本站公开资格导入;清理只作用于本站索引。校验排序、可过滤字段、同步时机以及更新/撤稿/分类隐藏后索引变化。索引命中应结合当前数据库权限重新确认。搜索入口应有服务端 GET 表单处理;目前无 JS 时 `/?s=Clash` 仍显示首页。 + +**验收:** 新索引所有 ID 与本站一致;Clash 和中文节点词能返回真实匹配;无匹配、后端故障和权限变化各有正确状态;FN_B 或其他索引未变化。当前通用 `articles` 索引不得未经归属核实直接删除或重建。 + +### SEO-017 建立空资源与检测失败的发布门槛 + +**优先级:P0 内容。证据:E12。** 连续三篇最新文章显示 0 个可用节点,却仍沿用“最新高速”标题。问题并非必须禁止所有零结果页面,而是发布内容必须准确反映实际检查结果,且不能把系统故障包装成有效更新。 + +接收结构化的 `检查状态、检查时间、有效数量、失败原因类别、资源版本`,不要只解析标题字符串决定是否发布。明确区分:没有执行检查、检查失败、检查完成且为零、检查完成且有有效资源。失败时保留上次有效记录并标明时效,或提供真实的状态说明;不生成伪装成成功的新索引页面。对旧资源做可用性提醒,不能保证“永久高速”“全地区可用”。 + +**实施范围:** FNA_V3 接收端的校验和发布策略;上游 NodeHub/SubCheck 的字段或检测变更要在对应项目单独授权和验收,本计划不自动修改它们。 + +**验收:** 用无真实订阅的固定样例覆盖四种状态;页面标题、数量、可见说明、索引资格和 sitemap 一致。真实检查数据缺失时展示未知,不把 0 和未知混为一谈。先核实本轮零记录成因,再决定是否处理历史文章。 + +### SEO-018 建立稳定资源入口和日更归档策略 + +**优先级:P1。** 建议为“现在能用什么、如何使用”提供一个稳定且持续维护的地址,将日期快照作为支持信息。稳定入口显示最近有效结果、验证时间、适用客户端、导入说明和常见失败处理;用户不必每天重新找到另一个日期 URL。 + +日更页分三类处理:有独立验证记录或重要变化的可以保留索引;仅重复模板、没有新信息的保留浏览但不争取索引;已经失效且没有历史价值的按策略退出。七天窗口可以作为资源风险管理的一部分,但不应无差别决定所有内容的长期价值。180 天清理也需服从保存、合并、删除合同。 + +**实施范围:** 稳定资源页内容、日更模板和归档策略;尽量复用现有视觉组件。禁止把所有历史日期页统一跳转到今天而忽略是否等价。 + +**验收:** 稳定入口即使某天检查失败仍能如实解释状态;日更页有明确的历史身份并能返回当前资源入口;长期教程不因资源窗口到期被误关索引;历史页去留有理由和恢复记录。 + +### SEO-019 处理真实重复文章与跨平台内容 + +**实施进展(2026-10-27):** 原重复组5的`m173`、`m174`已保留URL并分别重写为Mac与Linux桌面教程,平台安装和排错步骤不同,本地API版本1。原重复组1—4未处理;下表保留审计时的证据,不代表当前仍有五组重复。 + +**优先级:P1。证据:E11。** 本轮发现 5 组原始正文 HTML 完全相同,合计 13 篇: + +| 重复组 | 文章 slug | +| --- | --- | +| 1 | `ssi20260922`、`ssi20260907`、`ssi20260906` | +| 2 | `ssi20260909`、`ssi20260908` | +| 3 | `ssi20260827`、`ssi20260826`、`ssi20260825`、`ssi20260824` | +| 4 | `ssi20260823`、`ssi20260822` | +| 5 | `m174`、`m173` | + +重复正文不代表整个页面完全相同:标题、日期、分类等仍可能不同。`m167` 与 `m173/m174` 标题也相同,但正文并非全部逐字相同。应检查任务意图:如果是同一份跨平台说明,选一个主文,其他真正等价页面合并;若 Windows、macOS、Linux 各有独立安装、权限和排错步骤,则补成不同页面。 + +**验收:** 每个重复组有“保留独立/合并/历史 noindex”的理由;已认可合并使用一跳映射、更新内链和 sitemap;不能仅根据哈希自动删除。主文选择要考虑现有 URL 和后续获得的流量/外链证据,不能只认数字最小的一篇。 + +### SEO-020 提升客户端教程的任务完成能力 + +**实施状态(2026-10-27):本地正文更新完成,设备实测及生产验收未做。** “客户端”已改为“入门教程”并保留`/client`,迁移文m167归入进阶,与DNS专题并列。原七篇旧教程全部处理,另有Windows纯入门和DNS新文,共九篇;Android分别为v2rayNG和Clash Meta,iOS聚焦Quantumult X,Mac拆为选型下载与操作,Linux按桌面发行版和终端代理单独组织。四篇最后更新均经本地API版本1发布,当前完整版本与实际关联以[写作索引](../content/WRITING.md)为准。来源、图解、目录、内链锚点、1360/390页面及栏目已核对;未做平台客户端真机联网测试、提交或生产发布。因此保持部分验收状态,不把文章页面检查写成设备操作成功。内容源、证据与回退见[教程栏目维护](TUTORIALS.md)。 + +**优先级:P1。** 2026-10-22审计时,7 篇客户端正文约 138–355 字,多为简短介绍和项目/下载链接。字数本身不是问题;从实际内容看,很多安装、导入和排错步骤仍需要用户到别处寻找。 + +逐篇按用户任务补充:支持的平台与当前核实版本、官方项目与下载来源、安装前提、订阅导入步骤、正常工作的可见验证方式、常见错误与处理、维护状态、最后核验时间和必要截图。只有确实执行过才写“实测”;未核实的软件更新状态和下载安全性应明确待核实,不能根据旧文章继续承诺兼容性。 + +优先完善已存在的少数教程,再考虑新增。避免为了覆盖关键词而自动生成一套只有平台名称不同的文章;也不使用目标字数或重复问答堆篇幅。 + +**验收:** 一位目标平台新用户可按文档完成指定任务;链接来源、版本和步骤有核验记录;每篇明确自己解决的问题;内容与标题、摘要、schema 一致。Google 对有帮助内容强调实质价值和真实经验,而不是固定篇幅。[Google 内容质量指南](https://developers.google.com/search/docs/fundamentals/creating-helpful-content) + +### SEO-021 明确来源、验证和跨站内容差异 + +**优先级:P1。** 代码和项目关系显示文章可由上游分发。分发本身不等于垃圾内容,但如果多个站点只更换域名、日期或少量词语而重复发布,会缺乏独立价值。 + +记录资源来源类型、验证方法和时间、本站新增的信息。长期教程优先增加真实操作、限制条件和本地用户的具体问题;引用第三方内容时核实出处和使用许可。避免把免费资源数量、覆盖地区或速度当成未经测试的质量承诺。新站是否与原站同时提供相同完整内容,应随 D01 明确,不能默认复制站自然拥有独立排名价值。 + +**验收:** 每种内容模板能说明本站贡献;核心承诺能追溯到证据;发布失败不会换个日期再次生成看似新内容。Google 针对的是以操纵排名为目的、大规模产生低价值内容的行为,不能仅因自动化就认定违规,也不能声称本站已受处罚。[Google 垃圾内容政策](https://developers.google.com/search/docs/essentials/spam-policies) + +### SEO-022 作者、编辑责任与真实互动数据 + +**优先级:P1。证据:E14、E16。** 当前作者位置显示站点名并链接首页,未见独立的作者/编辑说明入口;代码还有自动注入点赞的功能,不能将这些计数当成真实用户评价或用于评分标记。 + +根据实际运营情况提供关于本站、联系/反馈、编辑与验证方法、推广关系说明。可以使用真实的团队或组织身份,不必虚构专家、头像、资历或个人作者。对于非真实点赞,建议停止将其表示为真实用户反馈,或明确改为站内推荐分;最终方案作为业务决策,不在本轮擅自清空计数或停任务。 + +**验收:** 作者/发布者可辨认且有有效说明入口;相关主张真实;“最近更新”不由互动驱动;没有把自动点赞包装为 AggregateRating 或用户评论。关于页是信任信息的一部分,不是添加后就获得某个 E-E-A-T 分数的按钮。 + +### SEO-023 推广链接、广告与正文体验 + +**优先级:P1。证据:E17。** 新 DPL 组件已有广告标识和 sponsored,应保留。仍需核实 160 篇正文中旧 `fuuu.cloud` 链接的商业性质:属于推广/付费推荐的应正确标记;一般编辑引用无需一律 nofollow。 + +检查广告不会伪装成下载按钮,不遮挡主要内容,不导致布局突然移动。当前 390px 样本中首页首批文章约在 y=438px,Windows 分类第一张文章卡片约在 y=695px;这表明分类页广告加大图占用了较多首屏,但不是已确认的搜索处罚。先观察真实使用任务和性能,再决定是否在保持品牌样式下调整间距、信息密度或顺序;三款已批准广告不因这份建议自动撤掉。 + +**验收:** 组件广告与正文推广分开检查;需要 sponsored 的链接全部正确;主任务可识别、可完成;手机无误触和遮挡;广告尺寸预留稳定。Google 建议用 sponsored 标记广告或付费链接。[Google 外链属性说明](https://developers.google.com/search/docs/crawling-indexing/qualify-outbound-links) + +### SEO-024 添加匹配真实内容的结构化数据 + +**优先级:P2。证据:E15。** 当前没有 JSON-LD,已有面包屑 itemprop 又缺少完整的结构。建议基础规则和日期修正后再添加: + +- 首页:真实的 WebSite 名称和 URL;组织资料真实、完整时再加入 Organization。 +- 正文:适合文章内容的 Article 或 BlogPosting,包含准确主题、规范 URL、真实作者/团队、相关图片、首次发布和实质更新时间。 +- 内容层级:BreadcrumbList,采用与可见面包屑一致的名称和 URL。 +- 普通分类可以使用语义合适的 CollectionPage/ItemList,但不把它们宣传为必然出现的 Google 富结果功能。 + +**验收:** JSON 可解析且正确转义;数据与用户可见内容一致;URL、日期、作者、图片能验证。Article 与 Breadcrumb 使用支持的富结果验证方式;WebSite 站点名称使用 schema 验证及后续搜索平台检查,不能要求 Rich Results Test 必须展示一个它不支持的站点名称结果。禁止虚构评分、作者或把资源页假装成新闻/商品。 + +这些标记能帮助理解及获得适用展示资格,但不保证富结果或排名改善。[Article](https://developers.google.com/search/docs/appearance/structured-data/article)、[Breadcrumb](https://developers.google.com/search/docs/appearance/structured-data/breadcrumb)、[站点名称](https://developers.google.com/search/docs/appearance/site-names)、[结构化数据质量规则](https://developers.google.com/search/docs/appearance/structured-data/sd-policies) + +### SEO-025 修复分享地址和社交预览信息 + +**优先级:P2。证据:E16。** 当前文章复制按钮输出首页地址,用户分享后无法直接到达原文。通用 OG 图片为相对地址,文章 OG 图片则依赖外部资源。 + +复制当前文章规范链接;OG URL 与 canonical 共用生成规则;图片使用环境正确的绝对 URL,校验实际存在、类型、尺寸与内容相关性;按目标分享平台需要补充卡片字段。favicon 与公开品牌一致。不要为满足社交卡片而新增与正文无关的图片承诺。 + +**验收:** 从两篇不同文章复制分别得到对应 URL;带跟踪参数的访问复制后得到干净主地址;预览图片与标题正确,真实线上爬虫取图在部署阶段验证。OG 本身不是 Google 排名提升保证,但分享错误是明确的产品缺陷。 + +### SEO-026 图片语义、尺寸和加载方式 + +**优先级:P2。证据:E15。** 当前卡片封面使用 CSS background,Google 的图片发现无法按普通 img 处理;当前 HTTP 样本没有缺 alt 属性的图片,DPL 装饰性 logo 空 alt 合理。导航两个 logo 缺少 HTML 宽高,不代表已经实测产生 CLS。 + +有内容意义的封面使用可保持原样式的 `img/picture`,提供真实相关的 alt、尺寸和合适的响应式资源;装饰图保持空 alt。按实际 LCP 元素决定加载优先级,首屏关键图不要统一 lazy,屏外内容再延迟加载。先核实资源大小、缓存与图片用途,再决定 WebP/AVIF、srcset、预连接等;不要为未知外站盲目添加 preconnect。 + +**验收:** 原视觉布局保持;有意义的图片可被 HTML 发现;装饰图不过度描述;图片加载前后布局稳定;不同视口不下载明显过大的资源;404、重定向及跨域资源响应在授权的部署验收中确认。[Google 图片指南](https://developers.google.com/search/docs/appearance/google-images) + +### SEO-027 手机端与无障碍完整验收 + +**优先级:P2。** 本轮 320px/390px 样本没有横向溢出,320px 菜单展开后位于 x=0–256,含 8 个链接;不需要无依据重做响应式布局。仍应核查完整功能,而非只看截图。 + +修复只有图标的菜单/搜索按钮可访问名称,验证键盘焦点、菜单开关、返回、搜索、加载更多、分享及错误提示。禁用 JS 或脚本失败时,正文、主要导航和分页仍应可用;搜索应有服务端表单后备。移动端隐藏了部分摘要、日期、侧栏和面包屑,重要解释和必要入口应在主内容中仍可找到。 + +**验收:** 320、390、768、1280px 代表性页面;正文不截断关键步骤;键盘可完成主要操作;字体可读;不以隐藏给搜索引擎的额外文本弥补信息缺失。Google 主要依据移动版本内容处理索引和排名。[Google 移动索引指南](https://developers.google.com/search/docs/crawling-indexing/mobile/mobile-sites-mobile-first-indexing) + +### SEO-028 建立正式构建性能基线并按瓶颈优化 + +**优先级:P2。** 当前是 Vite dev 模式;外部图片和统计被测试浏览器阻止。这样的环境不适合宣布线上 Lighthouse 得分或 Core Web Vitals 已通过。 + +已确认公共 JS 引入 Bootstrap、jQuery、InfiniteScroll、Clipboard,主 JS 源码约 34KB,基础主题 CSS 源文件约 578KB,并包含滚动日志和多种旧交互逻辑。它们是检查方向,不是实际传输量或慢站结论;也不能仅因使用 jQuery 就要求重写。 + +后续在获准的构建验证阶段记录正式资源的压缩后体积、未使用代码、长任务、字体、LCP 资源、图片重量及 TTFB。先按可测瓶颈优化:删除无用代码、按需加载、减少滚动布局计算、合适字体策略、压缩和长期缓存静态哈希文件。数据库索引只在 EXPLAIN 或慢查询证明需要时调整;167 篇规模不预设数据库是瓶颈。 + +**验收:** 有同一设备/网络条件的改前改后对照,功能无回归。上线后以真实用户第 75 百分位为主要口径,目标 LCP ≤2.5s、INP ≤200ms、CLS ≤0.1;实验室结果用于定位问题,不替代真实用户分布。[Google CWV 指南](https://developers.google.com/search/docs/appearance/core-web-vitals)、[web.dev 阈值与分位定义](https://web.dev/articles/defining-core-web-vitals-thresholds) + +### SEO-029 缓存与发布、撤稿、到期一致性 + +**优先级:P1,开启整页缓存前完成。证据:E18。** 当前整页缓存关闭,不应把默认 7 天 TTL 说成现有线上缓存故障。模型 saved/deleted 只尝试失效首页,分类、标签、详情、sitemap 及年龄变化缺少完整安排。 + +设计缓存键和失效范围,确保主域、路径、有效分页参数和必要响应差异被正确区分。新增文章影响列表和 sitemap;正文更新影响详情及摘要;撤稿/隐藏分类影响全部公开入口;到期即使没有数据库写入也会改变 noindex 与 sitemap。对点赞状态、会话、CSRF 等个性化内容核实整页缓存适用性。静态资源缓存和 HTML 缓存分别配置。 + +**验收:** 分页缓存互不串页;两个匿名会话不混淆状态;新增/撤稿/隐藏/到期后在明确时限内一致;不靠“全站清缓存”掩盖缺少失效合同;缓存关闭与开启均通过关键 SEO 用例。 + +### SEO-030 文章接收、更新与删除的发布合同 + +**优先级:P0,公开部署前。证据:E19。** 运行时路由表显示文章接收接口只挂 web 中间件,且 API 路径跳过 CSRF。接收逻辑直接设为发布并会触发资源读取、搜索同步、IndexNow 或通知。尚未确认生产是否另有边缘保护,本轮没有发送接收请求。 + +上线前为调用方建立明确认证、请求结构校验、允许字段、幂等标识和发布门槛;内容 HTML 采用与可信来源匹配的清洗策略,避免未知内容注入公开页面。编辑字段与上游覆盖字段分开,避免手工优化的标题/简介下一次分发就被覆盖。内容成功保存、标签同步、缓存失效、搜索更新和外部通知应有可追踪的顺序与失败恢复。 + +删除规则同样重要:当前批量删除不一定触发逐模型事件,不能假设缓存/搜索/推送会自动同步。无替代内容正确退出;有真正等价替代才重定向。点赞类写入也应使用合适的写请求,避免 GET 改业务状态,本轮未调用该接口。 + +**验收:** 未授权请求不能发布;同一消息重放不产生重复页;零资源/失败数据按策略处理;撤稿和批量清理后所有公开入口一致;外部服务失败不造成“页面显示发布成功但实际丢失”。测试使用独立数据库和外部服务替身,不触发真实推送或通知。 + +### SEO-031 正式主机、HTTPS 与 HTTP 服务质量 + +**优先级:P0,部署时。** 当前本地回环 HTTP 不是 HTTPS 问题的证据。生产上线后需要单独验证服务器、代理和 CDN 实际行为。 + +确定唯一主机与 HTTPS;已存在的 www/非 www、HTTP/HTTPS 别名使用明确一跳规则。框架正确识别代理协议和主机,避免生成 HTTP canonical 或错误域名。机器人不应遭遇无必要的登录、验证码、WAF 挑战或长期 5xx;同时不靠伪造 User-Agent 放宽安全策略。页面、XML、robots、静态资源返回合适状态及 MIME 类型,错误页和维护页不返回成功正文。 + +**验收:** 使用获准服务器侧链路检查正式 host、重定向链、robots、sitemap、文章和资产;记录证书、HTTP 状态及代理识别结果。完整线上页面交互若需要,仍按项目网站访问规则执行。本地通过不能代替此项。 + +### SEO-032 本地、预发布和生产资源隔离 + +**优先级:P0,公开部署前。** 独立数据库不代表所有资源已隔离。当前副本保留原站配置与 Git 元数据,搜索索引名称固定,布局按 cfn 加载线上 Umami 脚本,还存在共享资源链接。 + +为各环境核对:数据库、搜索索引、缓存命名、会话、统计站点 ID、图片依赖、外部通知、IndexNow、后台任务、公开品牌、主域、站点验证文件及 Git 远端。非生产环境默认不向真实搜索平台提交 URL,不向生产统计混入测试访问。公开预发布优先访问控制并配合 noindex;单独 robots 禁抓取不是可靠的防收录方案。当前 127.0.0.1 仅本机可达,不应因此判断已被公开索引。 + +**验收:** 本地业务测试不会写入 FN_B 数据或索引,不会触发外部通知与生产统计;生产部署不带 dev hot 标记、调试输出、私密配置或本地 URL;站点验证文件匹配实际站点所有权;发布前已核实 Git 推送目标,避免把副本改动推回源项目。 + +### SEO-033 规范 IndexNow 及搜索提交 + +**优先级:P2。** 当前发布接收逻辑会调用 IndexNow,服务先 GET 检查 URL,只接受成功响应。这能避免部分无效新增,却不能完整表达删除通知;200 页面也可能是 noindex 或错误副本。 + +按正式环境、规范 URL、内容状态和变更类型决定是否提交;支持新增、实质更新和删除各自的处理。避免推送本地地址、预发布地址、未发布或无价值的失败快照;主域与 keyLocation 必须属于当前站点。提交过程要能失败重试、去重并记录状态,不能把接口接收成功等同收录成功。 + +**验收:** 本地使用替身验证,不实际发送;正式获准后单条核验目标主机、验证文件和返回结果;删除事件不因目标已 404 而被本地逻辑永远过滤掉。IndexNow 表示通知采用该协议的搜索引擎,不能当成 Google 通用收录接口。Google Indexing API 仅支持其指定的招聘及直播事件页面,不适用于普通节点文章。[IndexNow 协议](https://www.indexnow.org/documentation)、[Google Indexing API 适用范围](https://developers.google.com/search/apis/indexing-api/v3/using-api) + +### SEO-034 SEO 自动回归与数据样例 + +**优先级:P1,随每批实现。** 当前仓库测试只有首页 200 示例和恒真示例,不能防止 URL、索引和发布规则回退。本轮未执行这些与审计目标无关的示例测试,也没有新增业务测试或修改代码。 + +未来围绕外部行为建立测试:规范地址与别名、合法分页和越界、状态与索引资格、日期边界、sitemap 集合、公开入口、结构化数据转义、资源失败和撤稿一致性。使用固定时钟、隔离数据库和外部服务替身。避免只照抄内部实现断言,或把当前 167 篇和日期写死。 + +**验收:** 变更相应行为会让测试真正失败;每个已完成项目对应验收证据;本地浏览器补验 JS 和无 JS 路径;核心样式、三种广告和正常 API 合同没有无关回归。测试通过、页面验收、上线和真实搜索效果分别记录。 + +### SEO-035 搜索平台与业务效果监测 + +**优先级:P1,上线后。** 本轮没有生产搜索数据,不能确认哪些页面已经收录、用户通过哪些查询进入、Google 选择了哪个 canonical,也不能证明某项缺陷已造成多少损失。 + +获准后配置或核实实际站点的 Search Console;按目标渠道需要补 Bing 等平台。记录 sitemap 处理、页面索引原因、选定 canonical、查询与页面表现、地区/设备、人工处置及安全问题。服务器日志用于区分真实机器人抓取和普通流量;访客分析用于衡量实际使用,不记录订阅密钥、账号或敏感正文。 + +**验收:** 有可回溯的发布前基线或新站起始基线;页面类型与业务目标能分组分析;出现错误有明确负责人和处理方式。监测频率和通知自动化另行授权,本报告不创建定时任务。[Search Console 能提供的数据](https://developers.google.com/search/docs/monitor-debug/search-console-start) + +### SEO-036 发布、迁移、回滚与复核 + +**优先级:P0,实际发布时。** 如果 FNA_V3 替换原站,应尽量保留已有有效 URL;如果成为独立新站,应按新站处理品牌与内容差异,不能默认沿用旧站身份及所有权验证。 + +发布前保存代码、数据和相关配置恢复点;确认 Git 远端,提交并推送本任务范围,再让目标服务器更新到明确提交。对确需改动的 URL 建立逐条映射,避免批量跳首页、循环和链式跳转。按批次发布规则改动,保留对比和回滚依据;不要同时更换域名、技术栈、URL、内容和视觉而失去定位能力。 + +**验收:** 代码、数据库、配置和链接映射均有恢复办法;发布后完成授权范围内服务器侧检查;迁移前后有效页面数与 URL 集合差异可解释;真实页面验证按访问规则记录。若跨域迁移,采用当前搜索平台认可流程,持续保留必要的旧地址映射。[Google 迁移指南](https://developers.google.com/search/docs/crawling-indexing/site-move-with-url-changes) + +## 7 建议实施顺序与批次交付 + +编号是稳定引用,不表示必须机械按数字逐个开发。以下批次避免先加展示功能、后反复改底层规则。 + +| 批次 | 范围 | 本批应交付的可检查结果 | 进入下一批的条件 | +| --- | --- | --- | --- | +| A 方向与合同 | 001–003,明确 D02–D05;启动 034 的测试方案 | 品牌/上线角色、页面类型、URL 与索引矩阵;确认历史内容处理原则 | 关键策略明确,仍未知的生产域名可延后到发布前 | +| B 地址与发现路径 | 004–009、014 的基础内链;配套 034 | 唯一 URL、合法分页、错误状态、robots 协调、统一公开查询、正确面包屑 | 无 JS 可遍历;分页、别名、状态和索引矩阵一致 | +| C 页面信息与索引集合 | 010–013、015、016;配套 034 | 区分主题的标题/简介,真实日期,统一 sitemap,独立且正确的搜索索引 | 样本与全量机器检查通过;没有污染其他项目索引 | +| D 内容价值与发布质量 | 017–023,以及 030 的质量门槛 | 零结果/失败处理、稳定资源入口、重复内容决策、可完成任务的教程、真实来源和推广说明 | 内容承诺可证明;每日自动发布不会撤销人工优化 | +| E 展示与体验 | 024–028,以及 029 的缓存设计 | 合适的结构化数据、正确分享、图片加载、手机功能和构建性能对比 | 功能、视觉与性能有证据,非只看审计工具分数 | +| F 上线准备 | 029–033、036,补齐 034 | 环境隔离、发布认证、主域与 HTTPS、缓存一致性、迁移和回滚方案 | 所有 P0 发布条件满足,获得实际发布授权 | +| G 线上观察 | 035;按结果回到内容与性能项目 | 抓取、索引、点击及使用完成的对照记录 | 按真实数据持续迭代,不保证固定天数见效 | + +SEO-017 的问题会影响当前内容承诺,可在批次 A 确认政策后尽早处理,不必等待所有标题优化完成。SEO-030、032 在任何对外暴露或真实导入测试之前先完成必要隔离。批次之间可以独立验收;本地实现完成不自动授权部署。 + +### 单项完成记录格式 + +以后在对应项目末尾增加短记录,保留最初问题与最新状态,避免把建议列表误读成已经实施。 + +```text +项目编号:SEO-xxx +状态:待决策/待实施/进行中/本地验收通过/已发布/观察中/已关闭 +实际范围: +关键取舍: +验证证据: +样式和数据影响: +提交及发布状态: +剩余问题或下一步: +``` + +“本地验收通过”必须包含本地证据;“已发布”必须有明确环境与提交;“已关闭”指该项目约定目标达成,不代表整站 SEO 达到某个永久最高分。 + +## 8 验收矩阵与完成标准 + +### 8.1 最小功能和索引样例 + +| 编号 | 验收场景 | 核心检查 | +| --- | --- | --- | +| T01 | 首页和认可的免费节点别名 | 唯一主 URL;别名一跳;标题与职能一致 | +| T02 | 正确/错误父分类路径 | 正确 200,错误 404;导航不产生错误路径 | +| T03 | 第 1、2、中间、最后一页 | 内容不同且顺序稳定;分页 href;正确自指 canonical | +| T04 | 页码 0、负数、字符串、超界、重复参数 | 明确规范化或 404;没有空薄的任意 200 页面 | +| T05 | 分页叠加跟踪参数 | 保留页码,去掉非内容参数;robots 允许必要抓取 | +| T06 | 当前文章、过期历史文章、永久教程 | 公开状态与 index/noindex 符合内容合同 | +| T07 | 草稿、未来文章、隐藏分类及父分类 | 在详情、列表、标签、搜索、推荐、sitemap 中一致 | +| T08 | 索引到期临界时刻 | 固定时钟下详情和 sitemap 同步切换,不受八小时差异影响 | +| T09 | 更新正文与仅点赞 | 仅前者改变内容修改日期;schema/sitemap/页面一致 | +| T10 | 资源成功、真零、未知、检查失败 | 标题、状态说明、资源数和索引政策一致 | +| T11 | 有搜索结果、无结果、服务故障 | 结果来自本库;无结果正常 noindex;故障不伪装无结果 | +| T12 | 已合并、已删除、从未存在的文章 | 映射与 HTTP 状态正确;搜索和 sitemap 不残留 | +| T13 | 有引号、实体、长文本的标题与简介 | HTML/JSON 正确转义,简介纯文本,无虚假日期 | +| T14 | 一篇普通教程、一篇资源页、一页分类 | 按内容类型选择结构化数据,字段与正文一致 | +| T15 | 无 JS、JS 失败、直接进入分页后滚动 | 主内容可读;分页可走;不重复加载当前页 | +| T16 | 手机与桌面 | 主要内容和必要入口可用,菜单/搜索/分享可操作 | +| T17 | 缓存关闭与开启 | 不串页、不串会话;新增、撤稿、隐藏、到期及时一致 | +| T18 | 本地、预发布、生产环境 | URL、统计、搜索、缓存、外部发送和验证文件隔离 | +| T19 | 接收接口拒绝与幂等 | 未授权不能发布;重放不产生重复;失败可恢复 | +| T20 | 发布前后全量 URL 集合 | 200/301/404/noindex 变化有清单,关键旧链接可恢复 | + +### 8.2 技术完成标准 + +- 所有计划索引的页面均有可访问的规范 URL,返回有效 200,未被 robots、错误 noindex 或错误 canonical 排除。 +- 别名、分页、参数、内链、sitemap、OG 和推送使用同一套 URL 与资格规则。 +- 所有计划索引的页面能从公开 HTML 内链到达;不存在只靠滚动事件才能发现的必要下一页。 +- 不能公开的对象在所有入口一致隐藏;合法无结果与运行故障被区别处理。 +- 标题、简介和日期真实,重要主题彼此可区分;schema 与正文一致。 +- 内容发布能验证资源状态、处理失败、保护人工编辑,并完整同步缓存、搜索与索引集合。 +- 网站原有功能和已批准视觉方案无无关回退;构建和线上检查分开记录。 + +这些标准可由工程验收保证;实际收录率、展示形式和排名需要搜索引擎处理,不能作为“代码测试通过”的同义词。 + +## 9 上线后的效果判断 + +### 9.1 指标应分层 + +| 层次 | 应观察什么 | 如何解读 | +| --- | --- | --- | +| 技术健康 | 有效 URL、错误重定向、意外 noindex、sitemap 冲突、5xx | 先排除明显工程回退 | +| 发现和索引 | 抓取记录、索引原因、Google 选择 canonical、计划索引页面的状态 | 不要求每个无价值归档都进入索引;分母是计划索引集合 | +| 搜索表现 | 按主题/页面类型的曝光、点击、CTR、查询和地区/设备 | 同类页面比较;平均排名和 CTR 受查询组合影响 | +| 内容贡献 | 长期教程自然流量、稳定资源页回访、相关下一步使用 | 关注持续价值,不只看每日新页面数量 | +| 实际任务 | 订阅使用入口、教程完成反馈、搜索成功率、故障反馈 | 事件仅记录必要状态,不收集订阅秘密或共享账号正文 | +| 体验 | 真实用户 CWV、失败率、手机交互和资源加载 | 实验室改善不等于真实用户已全面改善 | + +### 9.2 建议观察窗口 + +- **发布当天:** 验证服务、URL、索引规则、主要页面及外部发送配置,没有重大回退。 +- **首周:** 观察新 URL 的发现、sitemap 处理、异常状态、搜索和关键功能;不足以据此宣布排名稳定。 +- **后续 2–4 周:** 对照页面组观察收录原因、查询与点击变化,结合抓取情况判断是否需调整。 +- **后续 4–8 周及更长:** 评估长期内容、稳定入口和归档策略;新站、低抓取频率或迁移可能需要更长时间。 + +这些是建议的复核节奏,不是收录时限或增长保证。比较相似星期和页面组,标记节假日、内容更新与其他外部变化;不要一次搜索、一次 Lighthouse 分数或一次流量波动就反转策略。 + +## 10 暂不优先做的工作 + +1. **不因 SEO 全面更换框架。** 当前首次 HTML 已有内容,先修路由、分页和质量规则。 +2. **不把关键词 meta、固定字数、标题字符数当主要目标。** 对 Google,meta keywords 不影响索引和排名;标题和摘要应清楚且符合实际内容。[Google 支持的 meta 标签](https://developers.google.com/search/docs/crawling-indexing/special-tags) +3. **不把所有分页 canonical 指向第一页,也不默认全部分页 noindex。** 它们展示不同文章,应按真实内容处理。 +4. **不把所有旧页面跳首页。** 只有内容等价或真正迁移时采用对应重定向。 +5. **不把全部标签和全部历史文章一次性开放索引。** 先判断独立意图、质量和保留价值。 +6. **不通过每日刷新日期、生成空薄文章、虚构作者或点赞制造“新鲜”和“权威”。** 应改善真实内容和发布流程。 +7. **不为凑富结果给所有页面添加 FAQ、评分、商品或新闻标记。** 页面类型和真实内容必须适合;有效 schema 也不保证展示。 +8. **不在没有需要时建设多语言、AMP、庞大 sitemap 分片或独立抓取预算系统。** 当前规模与问题不支持优先投入。 +9. **不将 dev 模式跑出的分数当线上 SEO 成绩。** 正式构建、外部资源和真实访客条件不同。 +10. **不为 Google AI 搜索另造一套“专用 SEO”。** 官方仍要求可发现、可索引、有价值的内容,并没有额外必需的专用标记;应优先完成本清单基础项。[Google AI 搜索功能说明](https://developers.google.com/search/docs/appearance/ai-features) + +## 11 证据入口与复核方法 + +### 11.1 主要代码入口 + +以下行号是 2026-10-22 本轮基准,后续修改可能变化;路径链接是持续入口。 + +| 检查内容 | 文件及本轮关键位置 | +| --- | --- | +| 页面路由、宽松分类与接收接口 | [routes/web.php](../../routes/web.php),首页/分类和 api/article 路由 | +| 分类解析 | [Web ArticlesController](../../app/Http/Controllers/Web/ArticlesController.php),50–54 行 | +| 列表、搜索、标签、详情查询 | [ArticlesService](../../app/Services/ArticlesService.php),146–280 行 | +| 全局标题、日期、canonical、OG、统计 | [app-layout](../../resources/views/components/app-layout.blade.php),1–52 行 | +| 列表标题和缺少分页链接 | [列表模板](../../resources/views/pages/articles/default/index.blade.php),1–68 行 | +| noindex、面包屑、日期、分享 | [详情模板](../../resources/views/pages/articles/default/show.blade.php),1–4、24–62、95–103 行 | +| 卡片语义、封面和分类链接 | [article-item](../../resources/views/components/article-item.blade.php),3–25 行 | +| 搜索表单与导航 | [nav-bar](../../resources/views/components/nav-bar.blade.php),27–46、105–113 行 | +| 滚动页码和搜索 JS | [app.js](../../resources/js/app.js),47–76、140–148 行 | +| robots | [RobotsController](../../app/Http/Controllers/RobotsController.php),11–19 行 | +| sitemap 集合及时间 | [SitemapController](../../app/Http/Controllers/SitemapController.php),12–25 行;[XML 模板](../../resources/views/sitemap.blade.php),11–16 行 | +| 搜索索引、日期、缓存事件 | [Articles 模型](../../app/Models/Articles.php),52–76、84–113 行 | +| 分类关联和状态 | [Categories 模型](../../app/Models/Categories.php),20、46–52 行 | +| 点赞与内容时间耦合 | [SyncArticleLikes](../../app/Console/Commands/SyncArticleLikes.php),21–55、72–80 行 | +| 180 天删除及调度定义 | [ClearDb](../../app/Console/Commands/ClearDb.php),26–37 行;[调度入口](../../routes/console.php) | +| 发布与上游数据覆盖 | [API ArticlesController](../../app/Http/Controllers/Api/v1/ArticlesController.php),35–90、96–239 行 | +| 外部搜索通知 | [IndexNowService](../../app/Services/IndexNowService.php),25–170、182–220 行 | +| 中间件与 CSRF 排除 | [bootstrap/app.php](../../bootstrap/app.php),14–25 行 | +| 新广告范围和保留要求 | [广告维护说明](ADVERTISING.md)及[广告组件](../../resources/views/components/dpl-article-ad.blade.php) | + +### 11.2 本轮证据保存 + +[审计基线数据](SEO_BASELINE_2026-10-22.json)仅保存脱敏后的计数、代表性本地响应、内容重复组、搜索匹配计数和相关源码哈希,便于以后对照。本文件承载解释与任务状态,JSON 不另行维护一份优化计划。 + +临时细节与受限浏览器截图位于 `/private/tmp/fna-v3-seo-20261022/`。临时目录可能被清理,不作为后续唯一证据;正文中的关键事实和项目内基线已经固化。没有把数据库导出、账号信息、凭据、订阅内容或完整文章正文写入本次文档产物。 + +复核时按以下方法重新取得现场证据: + +1. 读取当前项目资料、并行修改和服务状态,再记录待检查源码哈希。 +2. 以本地只读数据库事务统计文章/分类/标签,记录应用和数据库时基。 +3. 限定回环地址,不跟随外部重定向,不自动点击/请求点赞、API 或测试路由。 +4. 检查首页、真实分类路径、标签、全部文章、分页边界、robots 与 sitemap;解析标题、canonical、robots 和实际 href。 +5. 链接图从首页开始,沿实际 HTML 链接计算,不把手工塞入的文章地址冒充站内发现。 +6. 浏览器拦截全部非本地网络和有副作用请求,分别测试有 JS、无 JS、直接进入分页及手机宽度。对被拦截的线上图片不判断其真实可用性。 +7. 核实源码和业务数据差异,更新该基线或创建下一次有日期的证据快照;优化决策继续更新本文件。 + +### 11.3 本轮交付状态 + +- 已完成独立重新分析、230 个本地地址检查、当前数据库统计、搜索索引对照和受限浏览器复核。 +- 已完成本建议文档与基线保存;清单项目尚未实施。 +- 交付核对通过:36 个项目编号与总表一一对应,20 个验收场景,文内本地链接有效;195 个网站源码、资源及环境基准文件哈希未变化,文章/分类/标签已采集业务字段前后相同。GemDocs 离线文档检查通过。 +- 网站源码、样式和本地私密环境配置保持本轮基准;未改业务数据,未执行调度器、队列、发布接收或外部推送。 +- 为检查恢复了原本停止的本地 PHP 8103 与 Vite 5173 开发预览。框架正常请求产生的会话/缓存及 Vite 运行产物不属于业务优化修改。 +- 未提交、推送、部署;未访问项目线上网站,未验收线上收录、排名或真实用户性能。 + +## 首页展示调整(2026-10-27) + +按用户更正后的要求,`/`直接复用文章详情展示日期最新的一篇已发布免费节点文章,不限定当天。通过分类slug筛选,按created_at、id倒序选择,忽略置顶排序并排除未来时间;`/freenode`继续保留历史列表。首页绕过整页响应缓存,新的文章发布后下一次访问即可选取;未改全局时区、业务数据或其他栏目查询。无可用文章时使用现有空态。 + +验证:3项独立SQLite内存库测试、6项断言通过,覆盖旧日期文章、置顶、其他栏目、草稿、未来文章、同日期排序、空池和缓存边界。本地首页与免费节点列表HTTP 200,首页最新正文为fn20261021。未提交、推送或部署;首页与文章详情的canonical及noindex继承行为仍需在SEO-004/018中单独处理。 + +### 首页独立索引规则(2026-10-28) + +按用户要求修复首页继承过期文章noindex:详情模板以articles.home路由识别首页,首页固定index, follow;其他文章详情继续按分类过期规则,编辑签名预览仍优先noindex, nofollow。日期计算使用created_at副本,避免渲染过程中修改模型日期。实测首页、fn20261021详情、freenode栏目均200,分别index/noindex/index;首页无额外X-Robots-Tag。仅本地,未提交/推送/部署;canonical规则与生产配置不属于此次已完成范围。 diff --git a/docs/maintenance/TUTORIALS.md b/docs/maintenance/TUTORIALS.md new file mode 100644 index 00000000..bef58fc3 --- /dev/null +++ b/docs/maintenance/TUTORIALS.md @@ -0,0 +1,184 @@ +# 教程栏目与内容维护 + +状态:2026-10-27 本地内容更新;未提交、推送或发布。当前任务由“先重写一篇客户端文章”扩展为栏目改名及加入此前 DNS 进阶文章;随后按用户要求完成Android、iOS、Mac和Linux旧教程重写;当前文章与版本以写作索引为准。 + +## 栏目与文章入口 + +| 对象 | 本地数据库身份 | URL | 本次状态 | +| --- | --- | --- | --- | +| 入门教程 | categories.id=2,原客户端 | `/client` | 仅更名和更新简介,原平台子分类及 URL 保留 | +| 综合教程 | categories.id=10,根分类,排序1 | `/advanced` | 原进阶教程更名,地址和文章归属保留;无资源文章的时效 noindex 策略 | + + +文章标题、ID、稳定URL、源文件和正文关联统一维护在[AI写作与文章关联索引](../content/WRITING.md),本页只保留实现、验收与回退资料。 + +本地预览根为 `http://fna-v3.loc`。分类名称由数据库驱动,桌面和移动菜单共用 `global_nav_tree` 文件缓存;本次仅清除此键。没有改栏目路由、已有平台名或文章分发入口。 + +## 当前发布方式 + +2026-10-27起普通编辑文章使用[本站独立文章API](EDITORIAL_API.md),不经过ATOM;本文下方源文件/HTML/数据库的说明保留当前素材及历史实施证据,新稿由API完成渲染、版本和公开正文同步,不再以临时SQL脚本发布。Windows入门文章362已在免费订阅文案修正时显式接管为`verge-windows-start`,本地已发布API版本1;迁移和DNS两篇随后在移除顶部重复信息时通过API显式绑定原ID;当前版本以写作索引为准。 + +## 正文与排版 + +- 可编辑正文源:`docs/content/tutorials/windows.md`(纯入门)、`migration.md`(原迁移文章)、`dns.md`、`v2rayng-android.md`、`clash-meta-android.md`。 +- 同目录 HTML 为 CommonMark 生成结果,实际运行正文存于本地数据库。改 Markdown 后需要重新渲染和定点更新数据库,不能把仅修改源文件当成页面已变。 +- 当前文章模板对正文执行 `nl2br`。入库前先把 `
` 内换行编码成 `
`,其余 HTML 换行去除;避免代码块重复换行或样式结构损坏。
+- 公共教程样式:`public/css/tutorials.css`,限定 `.tutorial-body` / `.tutorial-category`;未改站点全局样式或广告。
+- 技术封面:`public/images/tutorials/windows-cover.svg`、`migration-cover.svg`、`dns-cover.svg`,为文字与路径图,不涉及既有 CFN 品牌插画池。
+- Windows 导入示例:`public/images/tutorials/verge-import.png`。来源为 Clash Verge Rev 官方快速入门 https://www.clashverge.dev/guide/quickstart.html ,原图 https://www.clashverge.dev/assets/guide/quickstart/verge_import.png 。图片旁保留来源及“界面可能与当前版本不同”,未声称是 v2.5.8 Windows 实机截图。
+- 入门教程第二张操作图:`public/images/tutorials/verge-system-proxy.png`,来自官方 quickstart 的 `https://www.clashverge.dev/assets/guide/quickstart/verge_enable_sysproxy.png`,图注保留来源与版本边界。
+- 列表模板仅为 `/client` 和 `/advanced` 增加栏目标题、简介和页面title/description。文章模板修正了原本相对路径的分类面包屑为站点绝对 URL。
+
+## 内容核验与边界
+
+2026-10-27 核对官方安装/发行资料,Clash Verge Rev 最新发行页指向 v2.5.8(2026-10-09)。文章对照官方 quickstart、profile、Windows FAQ;兼容性按安装文档,不承诺未经测试的连接速度。
+
+DNS 原稿的关键字段再次对照 Mihomo 官方 DNS、TUN 文档:dns-mode native、dns-hijack、节点域名独立解析、代理组后缀与 strict-route 的平台限制。文章明确区分 DNS 接管、加密和连接出口;保留浏览器独立 DNS、远端解析、IPv6 及故障状态验证限制。
+
+这是教程内容及网站页面验收;没有安装 Windows 客户端、导入真实订阅、切换用户代理或执行设备 DNS 泄漏测试。
+
+使用 Query Builder 事务定点更新,校验目标仅为本机 `fna_v3`、已备份行与当前行一致,并确认其他六篇未变化;未触发 Eloquent 保存事件、推送或 Scout 索引同步。现有搜索索引的环境隔离尚未在本任务确认,因此本地搜索结果未同步,不把栏目/详情验收写成搜索验收。
+
+## 页面验收
+
+两栏目及三文章分别在 1360px、390px 检查 HTTP 200、标题、导航、面包屑、教程图片、代码换行与横向溢出;另检查移动导航可展开并包含两教程入口。DNS 3幅图解、入门教程1幅流程图和2张官方操作图、迁移文的原有图文均可显示。入门正文不包含迁移内容;迁移文已从入门移至进阶,DNS末尾入门链接已指向新文章。
+
+所有浏览器请求按来源白名单,仅允许 FNA_V3、其 Vite dev 和本地 Resource V2;线上统计和历史文章的线上图片请求在发出前被拦截。没有项目线上访问或线上页面验收。
+
+证据:`/Users/hellcat/Documents/Codex/2026-10-22/fq/outputs/verge-beginner-verification.json` 与同目录桌面、手机截图。此处验收结果以最终回读为准。
+
+## 本次更正的回退
+
+2026-10-27用户明确入门只讲软件使用,将迁移文章移到进阶。更正前源码与两篇受影响数据库行保存在 `/Users/hellcat/Documents/Codex/2026-10-22/fq/work/verge-beginner/`,`applied.json`记录新入门ID362及更新后行。若撤回本次更正,先核对当前行未被后续修改,再恢复212和361,检查362无后续依赖后移除,并恢复相应正文源和维护说明;不要误用前一轮备份撤销栏目改名。其余文章本次事务前后哈希内容一致。
+
+## 首轮回退与后续
+
+本次工作和备份根:`/Users/hellcat/Documents/Codex/2026-10-22/fq/work/client-rewrite/`。
+
+- `clients-before.json` / `categories-before.json`:修改前7篇文章和8个分类。
+- `applied.json`:本次旧行、新行、实际新增ID及写入时间,权限0600。
+- `index.before.blade.php` / `show.before.blade.php`:基于已有并行修改保存的模板;`*.after.blade.php` 用于核对本次差异。
+- 回退先比较数据库当前行和回执中的已应用行;有后续修改或关联数据时先合并,不直接覆盖。恢复212及分类2原值,确认新增361/10未被后续使用后移除,并仅刷新导航缓存。模板按本次差异撤回,不能整份覆盖后续修改。删除新素材前检查是否被其他文章引用。
+- Markdown和生成HTML已随项目保存;数据库内容不是Git文件,上线前仍需单独设计并审核生产迁移,本次不构成部署。
+
+当前原七篇旧教程均已处理,另有Windows纯入门和DNS进阶文章,共九篇长期内容。iOS m170、Mac m172/m173、Linux m174的批量重写见下文;Mac/Linux原重复正文已按各自任务分开。本地内容完成不代表客户端真机联网或生产部署验收。
+
+## 免费节点场景文案修正(2026-10-27)
+
+删除Windows入门中不适用于本站公开免费订阅的“不要公开分享”提醒框;导入步骤指向`/freenode`的较新分享,节点失效时自然引导回免费节点页面。通过独立API显式接管362,保留原URL、标题、标签及创建时间,发布版本1;原正文保存在基线版本0,可按API流程回退。原始稿、请求和回执在`output/free-tutorial-fix/`,正文源及生成HTML已同步。接收器补齐既有图解使用的安全`small`标签,隔离测试19项149断言通过。公开页面桌面/手机核对见`output/free-tutorial-fix/article-verification.json`;未部署线上。
+
+本轮全库`check_docs.py`检查发现2项无关账号资源的生成视图过期;本次未修改那些资源,也未越范围重建。项目文章源、内链及本地页面验收已通过,相关维护引用逐项存在。
+
+
+## v2rayNG Android 入门重写(2026-10-27)
+
+按用户“再来一章”定点重写原文章208(m171),使用原稳定内容键`v2rayng-android-legacy`显式接管,保留地址、栏目及标签;本地API版本1,基线0保留旧文。移除“稳定性极佳”的泛化承诺与1.7.3第三方安装包链接,换为官方发行入口、架构选择、本站v2ray订阅、订阅分组更新、VPN授权、连接检查和日常排错。2幅HTML/CSS流程图明确标为示意;列表封面换为本地`public/images/tutorials/v2rayng-cover.svg`,不请求旧线上封面。教程有序列表补`list-style-type:decimal`,恢复被站点reset隐藏的步骤编号。
+
+依据为官方2.3.11发行页、发布文件Wiki、该tag的界面/中文资源/构建配置及Android VPN官方文档;源码取证在`output/v2rayng-rewrite/upstream/`。已核对本站本地资源页实际提供v2ray格式入口,没有请求其线上订阅文件。未安装Android客户端、未导入真实订阅、未做节点或真机联网实测。
+
+源文件、API草稿、发布回执和原文备份见`docs/content/tutorials/v2rayng-android.md/.html`与`output/v2rayng-rewrite/`。缓存、独立搜索索引和sitemap回执均done;签名预览及公开页1360/390排版、两幅图解、目录和内链检查见该目录`preview-verification.json`和`public-verification.json`。浏览器仅允许登记本地来源;未提交、推送或部署生产。回退使用API历史版本0生成新草稿后预览发布,不直接覆盖数据库;正文源与关系索引同任务同步。
+
+
+## Clash Meta for Android 入门重写(2026-10-27)
+
+原Clash for Android文章206(m169)改为Clash Meta for Android的完整使用教程,保留原ID、内容键`cfa-android-legacy`、URL、栏目和标签。官方发行页当时为v2.11.36;下载架构、系统要求、配置保存/激活、首页启动和代理模式按该tag的README、中文资源与界面源码核对,证据在`output/clash-android-rewrite/upstream/`。正文以本站Clash/Mihomo免费订阅为主线,包含2幅HTML/CSS图解、本地技术封面和基本排错;不采用旧CFA的下载入口,不声称真机连接已实测。
+
+v2rayNG文章208只在订阅格式说明处增加指向m169#import的链接;206同时指向m171#import。两篇由API同批发布,分别为版本1和2;原文备份、请求、回执、预览与公开页1360/390验收见`output/clash-android-rewrite/`。缓存、搜索、sitemap均done;保留原文章身份,两个Markdown和HTML源及关系索引已同步。浏览器只允许本地来源,未访问线上站点、未安装手机客户端或测试真实订阅,未提交、推送、部署。206基线0保留旧文;回退时需同时处理208新增的#import入向链接,不能只恢复206造成断链。
+
+
+## 日期标注(2026-10-27)
+
+用户指出文章头部2026-08-04与正文“更新于2026-10-27”容易混淆。核实206/208的created_at均为2026-08-04,原发布时间随旧文保留;正文日期是此次教程更新时间。共享详情模板在原日期前补“发布于”,与正文“更新于”区分,不伪改原发布日期,也不直接把数据库updated_at当作内容更新时间。仅本地页面模板和响应缓存更新,文章正文/版本不变。桌面与手机验证见`output/tutorial-date-label/verification.json`,未上线。
+
+
+## 去除正文顶部重复信息(2026-10-27)
+
+用户澄清要删除正文开头整行“入门教程 · Android · 更新于……”;上一节的日期语义说明并非用户所指。现已从五篇已整理教程中移除guide-meta整行,保留网站标题信息栏及文末资料核对,其他正文文字与标题、摘要、标签、封面、栏目均回读一致。正文源和HTML同步,写作规范明确后续不再加这类顶部行。通过API同批完成,迁移212与DNS361首次显式接管并保留基线0;当前版本见写作索引。请求、原文、回执和页面验证见`output/tutorial-meta-removal/`;缓存、搜索和sitemap均done,仅本地生效。
+
+
+## 剩余四篇平台教程批量重写(2026-10-27)
+
+用户授权“剩下的一起处理了”。原207/m170改为Quantumult X iOS安装、资源解析和连接;209/m172改为Mac客户端选择与官方下载;210/m173改为Clash Verge Rev Mac安装、订阅、系统代理;211/m174改为Linux桌面安装、订阅与终端代理验证。两篇旧CFW跨平台重复文现在按DMG、DEB/RPM、权限、桌面和终端代理的实际差异组织,保留各自URL,不合并或重定向。iOS区分Quantumult与Quantumult X,并说明本站通用订阅需要兼容的第三方资源解析器;不承诺任意节点兼容或真实可用。
+
+依据为Clash Verge Rev v2.5.8发行与官方文档、Apple应用打开说明、Quantumult X App Store 1.8.1与开发者配置、KOP-XIAO解析器作者源码和curl手册。原ClashX仓库本次404只用于说明旧入口无法核验。源材料在`output/remaining-tutorials/upstream/`;未安装客户端、未修改本机网络、未访问线上订阅或进行设备/节点实测。
+
+正文源为`docs/content/tutorials/quantumult-x-ios.md`、`mac-client-guide.md`、`verge-mac.md`、`verge-linux.md`及同名生成HTML。每篇2幅HTML/CSS图解,Mac操作文另含现有官方订阅截图并注明示例范围;4张本地技术封面替换不可直接继承的线上图片。正文不添加顶部重复信息行。
+
+通过本地独立文章API同批显式接管原ID,四篇均发布版本1,基线0保留旧文。草稿`ad7be55b-be07-4509-ab19-c50856c21bc4`,发布回执`34a14f98-58b5-4e3f-bc3c-7563a28755b7`;缓存、独立搜索与sitemap均done。原ID、slug、栏目、标签和头图开关回读一致,文章总数不因本批增加。备份、请求、回执、页面截图和验证在`output/remaining-tutorials/`。预览及公开页1360/390排版、图解、图片、目录与实际链接锚点通过;平台栏目标题与URL另行核验。浏览器仅放行登记本地来源,未提交、推送或部署生产。
+
+关系维护在写作索引唯一正文。回退使用API基线0生成新草稿,再预览发布;Mac下载指南、Mac操作、Linux和iOS间已有锚点依赖,回退某篇时须同步处理相应入向链接,不单独恢复缺少锚点的旧文造成断链。
+
+
+## 安卓缩略图单张试样(2026-10-27)
+
+用户要求去掉缩略图顶部英文、加入相关应用图标,先改一张。仅修改`public/images/tutorials/clash-meta-android-cover.svg`:移除“ANDROID · GET STARTED”,保留Clash Meta专名与中文入门标题;以官方v2.11.36启动图标的原始矢量路径制作蓝色M与橙色猫须图标。没有使用仓库中保留的旧ic_launcher-web.png猫图。
+
+原图、官方素材出处与回退备份在`output/tutorial-cover-sample/`,恢复同目录`clash-meta-android-cover.before.svg`即可回退。原文章封面URL不变,未修改文章正文、版本、其他封面或插画图池。安卓栏目桌面与手机实际裁切预览见`card-1360.png`、`card-390.png`及`verification.json`。仅本地样稿,待用户评价,不自动扩展到全部封面;未提交或上线。
+
+
+2026-10-27用户要求撤回上述单张缩略图试样:已使用`output/tutorial-cover-sample/clash-meta-android-cover.before.svg`原样恢复Clash Meta封面,字节比对一致。原顶部“ANDROID · GET STARTED”、文字和线条布局恢复;其他封面未改。图标试样仅保留在output作为历史,不再用于页面。仅本地文件恢复,未上线。
+
+
+2026-10-27按用户指定,将Windows、v2rayNG和Clash Meta三张技术封面的“GET STARTED”统一替换为“开始使用”,保留其他文案与布局;仅本地SVG文件修改,XML解析通过,未上线。后续同类封面沿用中文“开始使用”。
+
+
+2026-10-27补齐进阶栏目两张封面的中文标签:DNS封面ADVANCED改为“进阶教程”,迁移封面MIGRATION改为“迁移指南”。已检查全部9张教程SVG,无GET STARTED、ADVANCED、MIGRATION遗留;应用名、平台名与技术格式名保留,布局不变。仅本地素材更新,未上线。
+
+
+## 入门父级banner与综合教程更名(2026-10-27)
+
+按用户确认,`/client`改用与Windows子栏目相同的既有图片banner,复用其aBanner配置;标题为真实HTML H1“入门教程”,简介为HTML段落,置于图片下部的深色半透明区域。移除该页原先重复的白底标题区,空栏目和无banner时保留文字回退。图片保持固定比例,桌面banner位于文章列表列内,与子栏目一致;没有更改Windows子栏目或其他平台banner。
+
+同时categories.id=10的名称由“进阶教程”改为“综合教程”,保留sSlug=advanced、排序、简介、文章归属和URL。导航、栏目标题及文章分类名称由数据库生成;未改文章标题“Clash 进阶”这一主题描述。清除global_nav_tree和响应缓存;本次为栏目配置,未改文章版本。
+
+代码与栏目数据原始备份、精确改动和回读在`output/tutorial-category-banner/`。仅本地变更,未提交、推送或上线。回退时先核对无并行变化,仅恢复栏目2的aBanner、栏目10的sName与本次模板/CSS差异,不覆盖整个数据库或其他修改;随后清导航与响应缓存。
+
+验收完成:`/client`、`/advanced`、Windows子栏目及迁移文章在1360/390宽度均HTTP200、单一H1、无横向溢出;父级标题简介完整落在banner内,子栏目保持原样。导航、栏目页title与文章分类已显示“综合教程”,DNS缩略图的栏目标签同步更名。证据为该输出目录verification.json和截图。
+
+
+## 公开正文清理与父栏目banner统一更正(2026-10-27)
+
+用户指出“本文的核对范围”出现在公开文章中。该内容属于已入库正文,上线不会自动删除;现已通过独立文章API同批清理九篇教程。删除迁移文顶部核对框,以及文末“未进行真机实测/未修改本机网络”等内部过程说明,保留官方参考链接、实用兼容限制、配置注意事项和内链;不因此新增实测宣称。完整原文与核验范围仍在历史API版本、`output/tutorial-editorial-cleanup/*before*`及本文先前记录中。写作索引已加入公开正文不放内部验收记录的规则。
+
+清理稿预览通过后按hash发布,缓存、独立搜索和sitemap均done;HTML源已从API回读,标题、摘要、ID、slug、栏目、标签和封面保持一致。各文章最新版本见写作索引,备份、草稿、回执和公开页验证见`output/tutorial-editorial-cleanup/`。仅本地更新,未部署生产。回退时按对应前一API版本生成草稿预览发布,不直接恢复整个数据库。
+
+用户进一步明确父级banner必须与子级完全同款。因此撤销父级专用小字简介和深色蒙层CSS:入门与综合栏目均使用同一list-cover结构、字号、间距、背景蒙层,显示中文栏目名与上标文章数量;综合栏目复用Windows现有图片banner配置。简介保留在meta description中,banner不再显示。栏目数量按同一分类查询范围的总行数计算,避免simplePaginate当前页仅两篇造成数字错误;入门含子栏目共7篇、综合2篇、Windows1篇,翻页总数不变。没有改文章列表筛选或分页行为。
+
+本次更正备份与数据操作位于`output/tutorial-category-banner/`,`categories.before-align.json`及`index-with-description.before.blade.php`保留更正前状态;`ArticlesService.before-count.php`保留计数变更前代码。桌面/手机计算样式对比、真实总数、无副标题与公开页面截图见aligned-verification.json及aligned-*.png。两项均仅本地完成,无提交、推送、上线。
+
+
+## 全部教程读者内容复查(2026-10-28)
+
+按用户要求,复查现有九篇教程的正文、摘要、图注及封面。七篇定点清理,Windows纯入门和Mac操作文未发现同类残留、保持原样。删除或改写“本页旧文”“页面原先介绍”“这次沿用原地址”“核对本文时”等内部编辑历史和核验过程;版本信息保留为明确的适用/示例版本,系统要求和配置限制保留。Android两篇文末移除仅用于编辑取证的界面实现/构建源码链接,保留官方下载、项目和实用参考;Mac下载指南摘要改为读者的选型任务。迁移文同时去除不适用于本站公开免费订阅的账户保密提醒,导入入口增加/freenode,旧订阅和自定义配置的迁移步骤保留。DNS中的“独立验收项”改为读者实际检查步骤。
+
+全部九篇摘要、封面文字和图注已核对;没有删除占位地址替换、平台兼容、节点有效性、DNS路径验证或配置合并等实用限制。未引入新的版本现状结论,未进行额外线上访问或设备联网测试。内部事实及完整修改前源保留在本文历史和output/tutorial-reader-audit-20261028/;不再发布到读者正文。
+
+七篇通过本站独立API原子更新;曾有两轮未发布草稿,最终发布冻结草稿以该目录draft-result.json为准,原始公开版本在before-*.json。请求、发布回执、逐项修改审计、正文回读及页面检查分别见audit.json、publish-result.json、source-verification.json、preview-verification.json和public-verification.json。缓存、独立搜索与sitemap均done。Markdown、HTML与写作关系索引同步,保留ID、slug、栏目、标题、标签和封面;仅Mac下载指南摘要作上述定点调整。文章最新API版本以写作索引为准,回退通过API历史版本重新建立草稿后发布,不直接恢复整库。
+
+预览最初因原有Vite本地开发服务未运行而缺少站点样式;已在原登记127.0.0.1:5187恢复dev服务后重新检查。没有执行生产构建、提交、推送或上线。浏览器只放行已登记本地来源,未访问生产站点或节点订阅。
+
+## 系统代理与 TUN 综合教程(2026-10-28)
+
+新增《系统代理和 TUN 有什么区别?接管范围、使用选择与排错》,稳定键/slug为`system-proxy-vs-tun`,本地ID365,归属综合教程。源文件为`docs/content/tutorials/system-proxy-tun.md`及API回读的同名HTML;封面为`public/images/tutorials/system-proxy-tun-cover.svg`,沿用现有文字与线条风格,标签使用“代理设置 · 综合教程”。正文以桌面客户端为范围,包含系统代理、TUN和接管/出口两阶段三张HTML流程图,以及组合说明、场景选择、切换检查和按现象排错。没有复制DNS配置片段,DNS专项操作链接既有正文。
+
+资料依据为Clash Verge Rev官方快速入门、名词解释、绕过说明、Windows FAQ,以及Mihomo TUN配置文档;准确URL与编辑取舍见`output/system-proxy-tun-20261028/research.json`。不同文档的默认协议栈描述有版本差异,正文未写固定默认值;没有把TUN描述为所有连接必经、必然防DNS泄漏或游戏加速。核验范围为官方资料与本地渲染/链接检查,未执行设备联网测试,未修改本机代理、DNS或路由;这些内部信息只保留在维护记录。
+
+Windows入门的TUN问答增加`#choose`入口;DNS教程配置片段前增加`#tun`入口,两篇其余内容和文章元数据保留。新文链接Windows、Mac和Linux实际连接章节,Linux终端显式代理章节及DNS接管/加密/出口章节。写作索引同步新增登记、实际关系与版本,移除已完成的TUN待写选题。
+
+独立API冻结草稿`06276f75-22f0-448d-b3b7-050662f1abc3`经预览后发布,回执`dc549d99-b9b4-40f6-b15d-0618c31bc1e6`;新文版本1、Windows版本4、DNS版本6。缓存、独立搜索、sitemap全部done。完整修改前正文、请求、回执、源文件回读与检查结果保存在`output/system-proxy-tun-20261028/`。
+
+1360和390宽度的三篇签名预览与正式页面均HTTP200,无横向溢出;目录与正文内链目标、锚点均通过,三张图已查看截图。综合教程栏目包含新文,banner总数为3,封面沿用现有样式。浏览器仅放行登记的本地来源。仅本地完成,未提交、推送或生产部署;旧文回退通过API历史版本生成草稿,不覆盖整库;新文如需撤下先处理上述入向链接。
+
+## 文章样式试改已撤回(2026-10-28)
+
+按用户“改回去先”的要求,已从`output/tutorial-style-20261028/tutorials.before.css`完整恢复`public/css/tutorials.css`,撤回本次主题样式设计,并删除写作规范中随之新增的“文章组件与排版”段落。文章正文、数据库与版本未变。试改截图和检查记录保留在输出目录,仅作历史记录,不代表当前样式。仅本地恢复,未上线。
+
+## 小标题蓝线定点调整(2026-10-28)
+
+用户在撤回整套样式后,明确只处理突兀蓝线。现仅向`public/css/tutorials.css`追加标题覆盖:`.post-content .tutorial-body h3::before`不再生成原蓝色渐变装饰,小标题使用左侧3px主题色竖线、适当左内边距与行高;h2/h3恢复block,修复全局inline造成相邻标题连行。主题色使用站点`--color-primary`,当前为#A758A5。其他目录、图解、表格、链接、字号和正文内容保持原样,没有重新引入已撤回的整体设计或对应写作规范。
+
+修改前样式与本地1360/390亮色、深色检查记录在`output/tutorial-heading-20261028/`。四种显示状态均无页面横向溢出、标题与后续元素无重叠,旧伪元素消失,竖线读取当前主题色;桌面和手机截图已查看。仅本地生效,无文章数据修改、提交、推送或上线。
+
+## 本地样式服务恢复(2026-10-28)
+
+用户反馈/advanced排版再次错乱。现场确认public/hot仍指向127.0.0.1:5187,但该端口无监听,导致Vite样式/脚本不可用,页面退化为原始HTML(双Logo及展开导航)。已按原配置恢复npm run dev,仅监听127.0.0.1:5187,Vite7.3.1启动成功;刷新后浏览器截图确认Logo、导航、栏目banner与文章卡片恢复,无横向溢出。未修改教程正文、数据库、模板、全局字号或生产环境。截图codex/output/advanced-styles-restored-20261028.png。恢复的是当前本地dev进程,不代表已配置登录自启或已核实此前进程退出原因。