重定向规则 #
什么是重定向? #
重定向是将一个 URL 指向另一个 URL 的机制。
text
用户访问 /old → 重定向到 /new
重定向类型 #
| 类型 | 状态码 | 说明 |
|---|---|---|
| 永久重定向 | 301 | 搜索引擎会更新索引 |
| 临时重定向 | 302 | 搜索引擎保留原 URL |
| 重写 | 200 | URL 不变,内容来自其他路径 |
配置方式 #
方式一:netlify.toml #
toml
[[redirects]]
from = "/old"
to = "/new"
status = 301
方式二:_redirects 文件 #
text
# static/_redirects
/old /new 301
优先级 #
text
netlify.toml > _redirects 文件
基本重定向 #
简单重定向 #
toml
[[redirects]]
from = "/old-page"
to = "/new-page"
status = 301
重定向到外部 URL #
toml
[[redirects]]
from = "/blog"
to = "https://blog.example.com"
status = 301
强制 HTTPS #
toml
[[redirects]]
from = "http://example.com/*"
to = "https://example.com/:splat"
status = 301
force = true
通配符 #
基本通配符 #
toml
[[redirects]]
from = "/posts/*"
to = "/articles/:splat"
status = 301
:splat 匹配 * 的内容:
text
/posts/hello → /articles/hello
/posts/world → /articles/world
多个通配符 #
toml
[[redirects]]
from = "/*/*/post"
to = "/posts/:splat"
status = 301
占位符 #
命名占位符 #
toml
[[redirects]]
from = "/posts/:year/:month/:slug"
to = "/blog/:slug?year=:year&month=:month"
status = 302
示例:
text
/posts/2024/01/hello → /blog/hello?year=2024&month=01
可选占位符 #
toml
[[redirects]]
from = "/posts/:slug?"
to = "/blog/:slug"
status = 301
查询参数 #
匹配查询参数 #
toml
[[redirects]]
from = "/search"
to = "/search-results?q=:q"
status = 302
query = {q = ":q"}
多个查询参数 #
toml
[[redirects]]
from = "/products"
to = "/shop?category=:cat&sort=:sort"
query = {cat = ":cat", sort = ":sort"}
URL 重写 #
基本重写 #
toml
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200
状态码 200 表示重写,URL 不变。
SPA 路由支持 #
toml
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
所有路由都返回 index.html,由前端处理路由。
代理 API #
toml
[[redirects]]
from = "/api/*"
to = "https://api.example.com/:splat"
status = 200
条件重定向 #
按语言重定向 #
toml
[[redirects]]
from = "/"
to = "/en/"
status = 302
conditions = {Language = ["en"]}
[[redirects]]
from = "/"
to = "/zh/"
status = 302
conditions = {Language = ["zh", "zh-CN", "zh-TW"]}
按国家重定向 #
toml
[[redirects]]
from = "/"
to = "/us/"
status = 302
conditions = {Country = ["US", "CA"]}
[[redirects]]
from = "/"
to = "/cn/"
status = 302
conditions = {Country = ["CN"]}
按角色重定向 #
toml
[[redirects]]
from = "/admin"
to = "/login"
status = 302
conditions = {Role = ["admin"]}
按用户代理重定向 #
toml
[[redirects]]
from = "/download"
to = "/download/ios"
status = 302
conditions = {UserAgent = ["iPhone", "iPad"]}
[[redirects]]
from = "/download"
to = "/download/android"
status = 302
conditions = {UserAgent = ["Android"]}
Signed Redirects #
什么是 Signed Redirects? #
使用签名令牌验证重定向请求。
配置 #
toml
[[redirects]]
from = "/protected/*"
to = "https://cdn.example.com/:splat"
status = 302
signed = "API_SIGNING_KEY"
生成签名 URL #
javascript
const crypto = require('crypto')
function generateSignedUrl(path, key) {
const expiry = Math.floor(Date.now() / 1000) + 3600 // 1小时后过期
const stringToSign = `${path}?expiry=${expiry}`
const signature = crypto
.createHmac('sha256', key)
.update(stringToSign)
.digest('hex')
return `${path}?expiry=${expiry}&signature=${signature}`
}
重定向优先级 #
规则顺序 #
规则按定义顺序匹配,先匹配的优先生效:
toml
# 这个规则先匹配
[[redirects]]
from = "/posts/hello"
to = "/articles/hello"
status = 301
# 这个规则不会匹配 /posts/hello
[[redirects]]
from = "/posts/*"
to = "/blog/:splat"
status = 301
最佳实践 #
将具体规则放在前面,通配规则放在后面:
toml
# 具体规则
[[redirects]]
from = "/posts/hello"
to = "/articles/hello"
status = 301
# 通配规则
[[redirects]]
from = "/posts/*"
to = "/blog/:splat"
status = 301
# 默认规则(SPA)
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
常见场景 #
场景1:网站迁移 #
toml
# 旧博客文章重定向
[[redirects]]
from = "/blog/:year/:month/:slug"
to = "/posts/:slug"
status = 301
# 旧分类页面重定向
[[redirects]]
from = "/category/:name"
to = "/topics/:name"
status = 301
场景2:API 代理 #
toml
# 代理到 Serverless Functions
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200
# 代理到外部 API
[[redirects]]
from = "/external-api/*"
to = "https://api.example.com/:splat"
status = 200
场景3:多语言站点 #
toml
# 默认语言
[[redirects]]
from = "/"
to = "/en/"
status = 302
# 中文用户
[[redirects]]
from = "/"
to = "/zh/"
status = 302
conditions = {Language = ["zh"]}
# 日文用户
[[redirects]]
from = "/"
to = "/ja/"
status = 302
conditions = {Language = ["ja"]}
场景4:维护模式 #
toml
[[redirects]]
from = "/*"
to = "/maintenance.html"
status = 503
force = true
场景5:移除尾部斜杠 #
toml
[[redirects]]
from = "/*/"
to = "/:splat"
status = 301
调试重定向 #
查看重定向规则 #
bash
netlify deploy --prod
部署后会显示重定向规则数量。
测试重定向 #
bash
curl -I https://your-site.netlify.app/old-page
查看响应头中的 Location 字段。
常见问题 #
问题1:重定向不生效
检查:
- 规则语法是否正确
- 规则顺序是否合理
- 是否需要重新部署
问题2:重定向循环
检查:
- 是否有相互重定向的规则
- force 参数是否正确使用
问题3:SPA 路由 404
确保添加了 SPA 重定向规则:
toml
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
_redirects 文件语法 #
基本语法 #
text
# 注释
/from /to status
# 示例
/home / 301
/blog /posts 301
通配符 #
text
/posts/* /articles/:splat 301
查询参数 #
text
/search /search-results 302 q=:q
条件 #
text
/ /en/ 302 Language=en
/ /zh/ 302 Language=zh
最佳实践 #
1. 使用 301 还是 302? #
- 永久移动:使用 301
- 临时移动:使用 302
2. 保持 URL 简洁 #
toml
# 好的做法
[[redirects]]
from = "/about"
to = "/about-us"
status = 301
# 不好的做法(复杂路径)
[[redirects]]
from = "/pages/about/company/info"
to = "/about"
status = 301
3. 避免重定向链 #
text
不好:A → B → C
好:A → C
4. 测试重定向 #
部署后测试所有重定向规则是否正常工作。
下一步 #
掌握了重定向规则后,继续学习 自定义 Headers 了解 HTTP 头配置!
最后更新:2026-03-28