HTTP 中的重定向
URL 重定向,也称为URL 转发,是一种为页面、表单、整个网站或 Web 应用程序提供多个 URL 地址的技术。HTTP 针对此操作提供了一种特殊的响应,称为HTTP 重定向。
重定向可以实现多种目标
- 站点维护或停机期间的临时重定向
- 更改站点 URL 后保留现有链接/书签的永久重定向,上传文件时的进度页面等。
原理
永久重定向
临时重定向
有时无法从其规范位置访问请求的资源,但可以从其他位置访问它。在这种情况下,可以使用临时重定向。
搜索引擎机器人和其他爬虫不会记住新的临时 URL。在创建、更新或删除资源时,临时重定向也用于显示临时进度页面。
代码 | 文本 | 方法处理 | 典型用例 |
---|---|---|---|
302 |
找到 |
GET 方法不变。其他方法可能会或可能不会更改为GET 。[2] |
网页由于不可预见的原因暂时不可用。 |
303 |
查看其他 |
GET 方法不变。其他方法更改为GET (主体丢失)。 |
用于在PUT 或POST 之后重定向,以便刷新结果页面不会重新触发操作。 |
307 |
临时重定向 |
方法和主体不变 | 网页由于不可预见的原因暂时不可用。当站点上提供非GET 操作时,它比302 更好。 |
[2] 规范不打算允许方法更改,但有些现有用户代理确实会更改其方法。307
是为了消除使用非GET
方法时的行为歧义而创建的。
特殊重定向
指定重定向的替代方法
HTML 重定向
HTTP 重定向是创建重定向的最佳方法,但有时您无法控制服务器。在这种情况下,请尝试在页面的<head>
中使用<meta>
元素,并将它的http-equiv
属性设置为Refresh
。显示页面时,浏览器将转到指定的 URL。
<head>
<meta http-equiv="Refresh" content="0; URL=https://example.com/" />
</head>
该content
属性应以一个数字开头,该数字指示浏览器在重定向到给定 URL 之前应等待多少秒。始终将其设置为0
以符合可访问性标准。
显然,此方法仅适用于 HTML,不能用于图像或其他类型的內容。
JavaScript 重定向
JavaScript 中的重定向是通过将 URL 字符串设置为window.location
属性来执行的,加载新页面
window.location = "https://example.com/";
与 HTML 重定向一样,这并非适用于所有资源,并且显然,这仅适用于执行 JavaScript 的客户端。另一方面,可能性更多:例如,只有在满足某些条件时才能触发重定向。
优先级顺序
有三种方法可以触发重定向,可以同时使用几种方法。但是哪个首先应用?
- HTTP 重定向始终首先执行——它们存在于甚至没有传输页面时。
- 有点令人惊讶的是,JavaScript 重定向在 HTML 重定向之前执行。这是因为
<meta>
重定向发生在页面完全加载之后,也就是所有脚本执行之后。 - 如果之前没有执行任何 HTTP 重定向或 JavaScript 重定向,则 HTML 重定向(
<meta>
)将在页面加载后执行。 - 如果在页面加载后发生任何 JavaScript 重定向(例如,单击按钮),如果页面尚未通过先前的方法重定向,则它将最后执行。
如果可能,请使用 HTTP 重定向,不要添加<meta>
元素重定向。如果有人更改了 HTTP 重定向但忘记更改 HTML 重定向,则重定向将不再相同,这可能会导致无限循环或其他问题。
用例
重定向有许多用例,但由于每次重定向都会影响性能,因此应将其使用量降至最低。
域名别名
保持链接有效
当您重组网站时,URL 会发生更改。即使您更新网站的链接以匹配新的 URL,您也无法控制外部资源使用的 URL。
您不希望破坏这些链接,因为它们会带来有价值的用户并帮助您的搜索引擎优化,因此您会设置从旧 URL 到新 URL 的重定向。
注意:此技术确实适用于内部链接,但请尽量避免使用内部重定向。重定向会产生明显的性能成本(因为会发生额外的 HTTP 请求)。如果可以通过更正内部链接来避免这种情况,则应更正这些链接。
对不安全请求的临时响应
对长时间请求的临时响应
在常见服务器中配置重定向
Apache
重定向可以在服务器配置文件或每个目录的.htaccess
中设置。
mod_alias
模块具有 Redirect
和 RedirectMatch
指令,默认情况下会设置 302
重定向
<VirtualHost *:443>
ServerName example.com
Redirect / https://www.example.com
</VirtualHost>
URL https://example.com/
将重定向到 https://www.example.com/
,其下的任何文件或目录也将重定向(例如 https://example.com/some-page
将重定向到 https://www.example.com/some-page
)
RedirectMatch
的功能相同,但它使用 正则表达式 来定义受影响的 URL 集合。
RedirectMatch ^/images/(.*)$ https://images.example.com/$1
images/
目录中的所有文档将重定向到不同的域名。
如果您不希望进行临时重定向,可以使用额外的参数(HTTP 状态码或 permanent
关键字)来设置不同的重定向。
Redirect permanent / https://www.example.com
# …acts the same as:
Redirect 301 / https://www.example.com
mod_rewrite
模块也可以创建重定向。它更加灵活,但也稍微复杂一些。
Nginx
在 Nginx 中,您可以为要重定向的内容创建特定的服务器块。
server {
listen 80;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
要将重定向应用于目录或仅某些页面,请使用 rewrite
指令。
rewrite ^/images/(.*)$ https://images.example.com/$1 redirect;
rewrite ^/images/(.*)$ https://images.example.com/$1 permanent;
IIS
在 IIS 中,您可以使用 <httpRedirect>
元素配置重定向。
重定向循环
重定向循环发生在后续的重定向遵循已经执行的重定向时。换句话说,存在一个永远无法结束的循环,并且永远找不到任何页面。
大多数情况下,这是服务器问题,如果服务器能够检测到它,它将发送 500
内部服务器错误
。如果您在修改服务器配置后不久遇到此错误,则很可能是重定向循环。
有时,服务器无法检测到它:重定向循环可能跨越多个服务器,每个服务器都没有完整的画面。在这种情况下,浏览器将检测到它并显示错误消息。Firefox 显示
Firefox 检测到服务器正在以永不终止的方式重定向此地址的请求。
…而 Chrome 显示
此网页存在重定向循环。
在这两种情况下,用户都无能为力(除非他们的客户端出现问题,例如缓存或 Cookie 不匹配)。
避免重定向循环非常重要,因为它们会完全破坏用户体验。