- 后端
- 文档
【免费下载链接】readthedocs.org
The source code that powers readthedocs.org
重定向(Redirect)是 Read the Docs 中保证文档 URL 长期稳定、避免读者遭遇 404 的关键机制。本文以 docs/user/user-defined-redirects.rst 为骨架,结合仓库中readthedocs/redirects与readthedocs/proxito的源码实现,系统讲解内置重定向与用户自定义重定向的四种类型、全部配置参数、限制条件与九个实战示例。读完本文,你将能够熟练在项目仪表盘中配置页面重定向、精确重定向、Clean/HTML URL 互转重定向,并用通配符与:splat占位符完成目录迁移、旧版本弃用、整站换域名等场景。
为什么要管理 URL 结构
随着时间的推移,文档项目常常需要重命名页面、移动内容、调整目录结构。如果放任 URL 结构变化而不做任何处理,用户最终会不断遇到 404 File Not Found 错误。虽然某些场景下 404 可以接受,但糟糕的用户体验通常应当尽量避免。
Read the Docs 提供两层重定向能力:
- 内置重定向(Built-in redirects):对所有项目自动生效,适合创建和分享指向文档的长期外部链接;
- 用户自定义重定向(User-defined redirects):由项目维护者自行配置,用于在文档内部移动内容时平滑过渡。
相关的最佳实践可参考 外部链接处理指南(关于创建和处理外部引用)、内容废弃指南(关于废弃文档中的功能与其他主题),以及配套的图文实操指南。
内置重定向:自动生效的四种跳转
内置重定向由 Read the Docs 服务器自动处理,无需任何配置,适用于所有项目。
/page/页面重定向:指向永远最新的页面链接
你可以通过/page/URL 前缀链接到某个具体页面,该链接会自动跳转到你的**默认版本(default version)**下的对应页面。这让外部来源的链接始终保持最新:
https://docs.readthedocs.io/page/guides/best-practice/links.html另一种做法是使用latest版本:把latest版本固定到某个具体版本上,然后始终链接到latest,例如https://docs.readthedocs.io/en/latest/guides/best-practice/links.html。
/根 URL 重定向:指向默认版本
指向文档根路径的链接(<slug>.readthedocs.io/)会重定向到项目设置中指定的默认版本(default version)。该机制同时适用于 readthedocs.io(Read the Docs Community)、readthedocs-hosted.com(Read the Docs for Business)以及自定义域名:
docs.readthedocs.io -> docs.readthedocs.io/en/stable/默认版本通常对应项目最近一次正式发布(release)。
警告:根 URL 重定向不能用于引用具体页面。
/只重定向到默认版本,而/some/page.html不会重定向到/en/latest/some/page.html。如需页面级跳转,请使用上面的/page/重定向。
/<lang>/语言根重定向:指向该语言的默认版本
指向文档语言根路径的链接(<slug>.readthedocs.io/en/)会重定向到该语言的默认版本。例如访问项目的英文根路径会跳转到其默认版本(stable):
https://docs.readthedocs.io/en/ -> https://docs.readthedocs.io/en/stable/rtfd.io短链接:便于输入
https://<slug>.rtfd.io形式的链接与readthedocs.io域名的处理方式完全相同,设计目的是方便用户输入、更短更易记,例如https://docs.rtfd.io。
这些内置跳转在源码中由ServeRedirectMixin.system_redirect(见 readthedocs/proxito/views/mixins.py)统一实现:它负责/与/page/*等由平台定义的系统级跳转,通过Resolver().resolve(...)计算出目标地址,并在响应头中写入X-RTD-Redirect: system标识。同时它会显式检查目标与当前请求的 hostname 与 path 是否一致,若一致则抛出InfiniteRedirectException,避免系统级无限重定向。
用户自定义重定向的四种类型
用户自定义重定向通过项目仪表盘(Admin > Redirects)配置,共有四种类型,对应源码 readthedocs/redirects/constants.py 中的TYPE_CHOICES。
Page Redirect(页面重定向)
Page Redirect允许你跨文档的所有版本重定向某个页面。由于它作用于项目的全部版本,From URL无需包含/<language>/<version>前缀(例如/en/latest),只需要页面的路径即可。
需要注意:页面重定向不适用于翻译(translations)和子项目(subprojects),这些项目需要各自配置自己的重定向规则。如果你需要针对特定语言或版本的 URL 进行重定向,请使用下面的 Exact Redirect,并填写完整路径。
Exact Redirect(精确重定向)
Exact Redirect会考虑完整的 URL(包括语言和版本),从而允许你为文档的特定版本或语言创建重定向。
Clean URL / HTML URL 互转重定向
如果你决定改变文档的 URL 风格,可以使用Clean URL to HTML(file/转file.html)或HTML to clean URL(file.html转file/)重定向,自动把读者引导到新的 URL 风格。例如某页面原来位于/en/latest/install.html,现在位于/en/latest/install/(或反之),用户都会被重定向到新地址。该类型在每个项目中每种只能配置一条(由 readthedocs/redirects/validators.py 中的校验逻辑保证)。
在仪表盘中配置重定向
完整操作步骤见图文指南,核心流程如下:
- 进入项目仪表盘,打开 :menuselection:
Admin > Redirects; - 点击 :guilabel:
Add Redirect,选择 :guilabel:Redirect Type; - 填写 :guilabel:
From URL与 :guilabel:To URL,表单会提供实时预览,方便你实验最终生成的规则; - 点击 :guilabel:
Save保存。保存后规则立即生效。
编辑与删除规则同样在 :menuselection:Admin > Redirects页面完成。重定向的顺序很重要:当多条规则匹配同一个 URL 时,列表中的第一条会被采用。你可以用上/下箭头调整顺序,新建的重定向会添加到列表最前面(拥有最高优先级)。
Redirect模型的完整字段定义见 readthedocs/redirects/models.py:除project、redirect_type、from_url、to_url外,还包括:
| 字段 | 类型/默认值 | 说明 |
|---|---|---|
force | Boolean, 默认False | 强制重定向:即使目标页面存在也应用跳转 |
http_status | 默认302 | HTTP 状态码,可选302 - Temporary Redirect(临时)或301 - Permanent Redirect(永久) |
enabled | Boolean, 默认True | 启用/禁用该规则 |
position | Integer, 默认0 | 规则执行顺序,配合上下箭头调整 |
description | String, 默认"" | 规则描述 |
限制与注意事项
原文档总结了以下关键限制,配置时务必留意:
- 数量限制:Read the Docs Community 用户每个项目最多 100 条重定向;Read the Docs for Business 用户的数量限制取决于其套餐。达到上限时会收到校验错误提示,并建议用通配符合并部分规则(校验逻辑见 readthedocs/redirects/validators.py,数量上限通过订阅功能
TYPE_REDIRECTS_LIMIT读取)。 - 默认仅对不存在的页面生效:默认情况下重定向只作用于不存在的页面(404 场景);Forced Redirect(强制重定向)允许你对已存在的页面也执行跳转。部分套餐才提供"即使页面存在也应用"选项。
- 不作用于 Pull Request 预览:重定向不会应用于拉取请求预览的域名,这类域名应视为临时性的,不应依赖其承载面向用户的正式内容。
- 可跳转到站外:
To URL中包含协议(如https://example.com)即可重定向到 Read the Docs 之外的 URL。 - 仅支持后缀通配符:通配符
*只能放在From URL末尾(后缀通配符),用于重定向匹配某个前缀的所有页面;前缀和中缀通配符不支持。 :splat占位符:若From URL使用了通配符,URL 中被通配符捕获的部分可通过:splat占位符引用到To URL中。- 尾斜杠兼容:无通配符的规则会同时匹配带或不带尾斜杠的路径,例如
/install同时匹配/install与/install/。 - 顺序优先:多条规则命中同一 URL 时,第一条生效;顺序可在项目仪表盘调整。
- 无限重定向保护:若检测到无限重定向,将直接返回 404,且不再应用其他规则。
实战示例大全
以下九个示例完整继承自原文档,覆盖从单页移动到整站迁移的全部常见场景。
1. 重定向单个页面
将example.html移动到子目录examples/intro.html:
Type: Page Redirect From URL: /example.html To URL: /examples/intro.html效果:
https://docs.example.com/en/latest/example.html→https://docs.example.com/en/latest/examples/intro.htmlhttps://docs.example.com/en/stable/example.html→https://docs.example.com/en/stable/examples/intro.html
如果只想对特定版本生效,改用精确重定向(注意使用目标版本和语言替换latest与en):
Type: Exact Redirect From URL: /en/latest/example.html To URL: /en/latest/examples/intro.html2. 重定向整个目录
把/api/目录重命名为/api/v1/,无需为每个页面单独建规则,用通配符即可:
Type: Page Redirect From URL: /api/* To URL: /api/v1/:splat效果:
https://docs.example.com/en/latest/api/→https://docs.example.com/en/latest/api/v1/https://docs.example.com/en/latest/api/projects.html→https://docs.example.com/en/latest/api/v1/projects.html
限定版本时的精确重定向写法:
Type: Exact Redirect From URL: /en/latest/api/* To URL: /en/latest/api/v1/:splat3. 目录重定向到单个页面
把/examples/目录的内容合并到examples.html单页:
Type: Page Redirect From URL: /examples/* To URL: /examples.html效果:
https://docs.example.com/en/latest/examples/→https://docs.example.com/en/latest/examples.htmlhttps://docs.example.com/en/latest/examples/intro.html→https://docs.example.com/en/latest/examples.html
4. 页面跳转到最新版本
让用户访问某个页面时总是跳到最新版本(例如安全策略页/security.html),结合通配符与强制重定向:
Type: Page Redirect From URL: /security.html To URL: https://docs.example.com/en/latest/security.html Force Redirect: True效果:
https://docs.example.com/en/v1.0/security.html→https://docs.example.com/en/latest/security.htmlhttps://docs.example.com/en/v2.5/security.html→https://docs.example.com/en/latest/security.html
注意:此处
To URL必须包含完整域名,否则跳转会相对于当前版本解析,结果变成https://docs.example.com/en/v1.0/en/latest/security.html。
5. 旧版本跳转到新版本
/en/2.0/版本已废弃,希望读者跳转到/en/3.0/:
Type: Exact Redirect From URL: /en/2.0/* To URL: /en/3.0/:splat效果:
https://docs.example.com/en/2.0/dev/install.html→https://docs.example.com/en/3.0/dev/install.html
注意:要让此规则生效,旧版本必须被禁用;如果版本仍处于激活状态,请使用
Force Redirect选项。
6. 创建短链接
让https://docs.example.com/security跳转到https://docs.example.com/en/latest/security.html,便于分享:
Type: Exact Redirect From URL: /security To URL: /en/latest/security.html效果(带与不带尾斜杠均可匹配):
https://docs.example.com/security(无尾斜杠)→https://docs.example.com/en/latest/security.htmlhttps://docs.example.com/security/(带尾斜杠)→https://docs.example.com/en/latest/security.html
7. 迁移文档到 Read the Docs
原来文档托管在https://docs.example.com/dev/,迁移到 Read the Docs 后位于https://docs.example.com/en/latest/,但用户书签仍保存着旧结构(如https://docs.example.com/dev/install.html)。用带通配符的精确重定向:
Type: Exact Redirect From URL: /dev/* To URL: /en/latest/:splat效果:
https://docs.example.com/dev/install.html→https://docs.example.com/en/latest/install.html
8. 迁移文档到另一个域名
用带强制选项的精确重定向把整个站点迁往新域名:
Type: Exact Redirect From URL: /* To URL: https://newdocs.example.com/:splat Force Redirect: True效果:
https://docs.example.com/en/latest/install.html→https://newdocs.example.com/en/latest/install.html
9. 更换 Sphinx builder(html→dirhtml)
将 Sphinx builder 从html改为dirhtml后,所有 URL 都会从/page.html变成/page/。创建一条HTML to clean URL类型的重定向即可把所有旧 URL 引导到新风格(反向迁移则使用Clean URL to HTML)。
源码级实现原理
数据模型与 URL 规范化
Redirect模型(readthedocs/redirects/models.py)在save()时做了两件关键事情:
- 规范化
from_url与to_url:normalize_from_url保证路径总是以单个/开头、不以/结尾,从而能同时匹配带与不带尾斜杠的路径;normalize_to_url则对非http(s)://开头的目标路径补上/前缀(models.py 的normalize_*方法)。 - 剥离通配符存储:若
from_url以*结尾,会把去掉*的部分存入from_url_without_rest字段并建立数据库索引,以便在数据库层做快速前缀匹配(models.py#L134-L150)。
数据库层匹配查询
匹配逻辑集中在RedirectQuerySet.get_matching_redirect_with_path(readthedocs/redirects/querysets.py#L50-L145)。它通过annotate把当前请求的 filename/path 注入查询集,在数据库层完成过滤:
- Page Redirect:无通配符时精确匹配文件名;有通配符时按
from_url_without_rest做前缀匹配; - Exact Redirect:无通配符时精确匹配完整路径;有通配符时前缀匹配;
- Clean/HTML 互转:当 filename 以
/index.html或/结尾时匹配clean_url_to_html,以.html结尾时匹配html_to_clean_url;根路径(/index.html或/)只匹配 page 与 exact 规则; - 默认排除
enabled=False的规则,并在forced_only模式下只筛选force=True的规则,然后按position、-update_dt排序取第一条。
无限重定向检测
无限重定向的典型形态是从 /dir/* 跳到 /dir/subdir/:splat:若目标文件不存在,/dir/test.html会依次跳到/dir/subdir/test.html、/dir/subdir/subdir/test.html……永无止境。_will_cause_infinite_redirect(models.py#L271-L293)通过检查"跳转目标是否为当前路径的子目录前缀"来识别此类循环:若to_url在:splat之前的部分以from_url_without_rest开头,且当前路径已以该目标前缀开头,则判定为无限重定向并返回None(此时平台返回 404 且不应用其他规则)。
校验规则
readthedocs/redirects/validators.py 中的validate_redirect统一服务于 Django 表单与 DRF 序列化器:
- 旧版
$rest通配符已移除,需改用*; *必须位于路径末尾(否则报"通配符必须位于路径末尾"错误);- 只有
from_url以*结尾时,to_url才能使用:splat占位符; - Clean/HTML 互转类型每项目每种仅允许一条;
- 新建规则时检查订阅功能规定的数量上限。
响应生成与开放重定向防护
readthedocs/proxito/views/mixins.py 中的get_redirect_response负责生成最终跳转响应:
- 调用
project.redirects.get_matching_redirect_with_path(...)得到命中规则与目标路径; - 若
To URL显式指向外部域名,则直接使用该 URL(但会对携带ticket等敏感参数的外部跳转记录警告日志); - 安全要点:若规则未显式指向外部域名,最终跳转会被强制约束在当前请求的同一域名内(
current_url_parsed._replace(path=...)),以防开放重定向(open redirect)漏洞; - 原始请求与跳转目标的 query 参数会被合并后一同拼入最终 URL;
- 跳转响应同时写入
X-RTD-Redirect响应头与缓存标签。
此外,readthedocs/proxito/redirects.py 中的canonical_redirect处理三类规范域跳转:HTTP → HTTPS、跳转到项目的规范自定义域名、子项目域名跳转到主项目域名(含 Pull Request 预览版本),并同样执行 from/to URL 相同的无限跳转检查。
测试验证
仓库测试对上述行为有充分覆盖,可作进一步参考:
- readthedocs/proxito/tests/test_old_redirects.py:验证
/page/*重定向、带 query 参数的页面重定向、无限重定向规避(test_page_redirect_avoid_infinite_redirect)、通配符重定向(test_page_redirect_with_wildcard)、重定向不适用于翻译与子项目(test_page_redirect_does_not_apply_to_translations_or_subprojects)、带/不带尾斜杠匹配(test_page_redirect_with_and_without_trailing_slash)以及跨域重定向(test_page_redirect_crossdomain); - readthedocs/proxito/tests/test_full.py:验证
/page/foo.html跳转到https://{host}/en/latest/foo.html; - readthedocs/redirects/tests/test_views.py:覆盖重定向视图层行为。
总结
重定向是文档项目长期健康运营的基础设施:内置重定向让外部链接永远指向最新内容,用户自定义重定向则让内容重构(改名、移动、合并、换版本、换域名、换 URL 风格)不再以 404 为代价。配置时牢记四条核心原则即可:默认只对 404 页面生效(需要时开启 Force)、通配符只能放在末尾、用:splat捕获片段、规则顺序决定命中优先级、跨域跳转必须带协议。在此基础上,结合readthedocs/redirects与readthedocs/proxito的源码实现,你可以准确预判每条规则在真实请求中的行为,并借助图文指南在仪表盘中快速落地。
- 后端
- 文档
【免费下载链接】readthedocs.org
The source code that powers readthedocs.org
相关推荐
Read the Docs 自定义 URL 重定向(Redirects)配置实战指南
Read the Docs 自定义 URL 重定向(Redirects)配置实战指南 本篇指南讲解如何在 Read the Docs 项目中配置用户自定义重定向
后端文档Read the Docs 文档外部链接管理最佳实践:内置重定向、页面永久链接与用户自定义跳转
Read the Docs 文档外部链接管理最佳实践:内置重定向、页面永久链接与用户自定义跳转 本篇技术指南聚焦 Read the Docs 文档项目中最容易被
后端文档BrewUI 的 Loadable 状态模式:用单一枚举建模 Homebrew GUI 加载状态的完整指南
BrewUI 的 Loadable 状态模式:用单一枚举建模 Homebrew GUI 加载状态的完整指南 BrewUI 是 Homebrew 官方 macOS
桌面应用开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考