重定向是指当访问特定 URL 的网页时,它会更改为不同的 URL。例如,某人在浏览器中访问“website.com/page-a”,但他们却被重定向到“website.com/page-b”。如果我们想要将特定页面重定向到新位置,更改网站的 URL 结构,删除 URL 中的“www.”部分,甚至将用户完全重定向到另一个网站(仅举几个例子),这将非常有用。
假设我们刚刚迁移了网站,想要关闭旧网站。但是,我们不希望旧网站上的所有页面都出现可怕的404 未找到错误。我们需要的是让这些旧链接重定向到我们新网站上的相同内容。
以下示例:我们希望将old-website.com/blog/post
重定向到new-website.com/blog/post
,以及所有使用相同 URL 格式的其他帖子。此外,如果我们的重定向可以向搜索引擎报告此更改是永久的,以便它们可以相应地更新,那就太好了。
那么我们如何实现呢?在开始之前,我们需要了解一些有关 HTTP 的知识。
HTTP 响应代码
每次我们输入 URL 或从浏览器发出请求时,我们都在使用超文本传输协议 (HTTP)。尽管这听起来像是科幻警察电影中非常酷的名字,但实际上它是我们从服务器请求 CSS、HTML 和图像等资产的过程。在发送请求后,这些资产会给出响应,例如“嘿,我在这里,让我们开始吧!”(响应代码HTTP 200 OK
)。有许多不同类型的 HTTP 响应代码,最熟悉的可能是404 未找到;网页可以使用 404 状态进行响应,但我们请求的任何其他资产也可以使用 404 状态,无论它是图像还是任何其他类型的资产。
每个 HTTP 响应都归类在某个三位数之下,因此404 未找到是 4XX 状态代码,以澄清它是客户端错误,而 200 属于 2XX 类别,表示它是某种成功消息。我们对 3XX 类别的 HTTP 响应感兴趣,例如301 永久移动或302 找到,因为这些是专门为重定向保留的状态代码。根据我们选择的方法,我们不一定需要了解这些代码,但对于其他方法来说,这些代码至关重要。
在本例中,我们将使用 301 重定向,因为一些网页浏览器或代理服务器会缓存此类型,使旧页面无法访问,而这正是我们想要的。
那么我们如何真正实现网页重定向呢?
HTML 重定向
也许将网页重定向到另一个 URL 的最简单方法是使用 Meta Refresh 标签。我们可以将此元标签放在任何 HTML 页面顶部<head>
内,如下所示
<meta http-equiv="refresh" content="0; URL='http://new-website.com'" />
content
属性是浏览器重定向到新页面的延迟时间,因此此处我们将其设置为 0 秒。请注意,我们不需要设置 HTTP 状态代码,但务必仔细检查上面的引号的奇怪打开和关闭方式(引号内有引号,因此它们需要使用不同的类型并匹配)。
尽管此方法是将网页重定向的最简单方法,但它也有一些缺点。根据 W3C 的说法,某些浏览器在使用 Meta Refresh 标签时会崩溃。用户可能会看到页面 A 闪现,然后才被重定向到页面 B。它还会在旧浏览器中禁用后退按钮。这不是理想的解决方案,并且建议完全避免使用它。
更安全的选择可能是使用 JavaScript 重定向网站。
JavaScript 重定向
使用 JavaScript 将网页重定向到另一个 URL 非常容易,我们只需要更改window
对象上的location
属性即可
window.location = "http://new-website.com";
JavaScript 非常奇怪,有许多方法可以做到这一点。
window.location = "http://new-website.com";
window.location.href = "http://new-website.com";
window.location.assign("http://new-website.com");
window.location.replace("http://new-website.com");
更不用说你可以直接使用location
,因为窗口对象是隐式的。或者self
或top
。
使用location
对象,我们还可以执行许多其他巧妙的操作,例如重新加载页面或更改 URL 的路径和来源。
这里有一些问题
- JavaScript 需要启用并下载/执行才能使其正常工作。
- 不清楚搜索引擎对此的反应。
- 没有涉及状态代码,因此您无法依赖有关重定向的信息。
我们需要一个服务器端解决方案来帮助我们通过向搜索引擎和浏览器发送 301 响应。
Apache 重定向
也许将网页重定向的最常见方法是在 Apache Web 服务器上的.htaccess
文件中添加特定规则。然后,我们可以让服务器处理所有事情。
.htaccess
是一个文档,它使我们能够向 Apache 发出命令,Apache 是在服务器上运行的软件。要将用户重定向到我们的新网站,我们将创建一个新的 .htaccess 文件(或编辑现有文件)并将其添加到旧网站的根目录。以下是我们将添加的规则
Redirect 301 / http://www.new-website.com
用户访问旧网站上的任何页面现在都会被重定向到新网站。如您所见,我们将 HTTP 响应代码放在重定向规则的最前面。
值得一提的是,这种重定向仅适用于启用了mod_rewrite
的 Linux 服务器,Apache 模块允许我们通过检查某个模式来重定向服务器上的请求 URL,如果找到该模式,它将以某种方式修改请求。大多数托管公司默认启用了此功能,但如果出现问题,最好联系他们。如果您想了解更多有关 mod_rewrite 的信息,那么 tuts+ 上有一个很棒的教程。CSS-Tricks 上也有很多.htaccess 代码段。
回到我们的示例,如果我们使用上面的代码,用户将访问“old-website.com/blog/post”,然后被发送到“new-website.com”,这不太友好,因为他们不会看到他们实际请求的页面。相反,我们将以下规则添加到.htaccess
文件中,以便将所有这些博客帖子重定向到正确的位置
RedirectMatch 301 /blog(.*) http://www.new-website.com$1
或者,我们可能想要非常具体地重定向单个页面。我们可以像这样添加规则
Redirect 301 /page.html http://www.old-website/new-page.html
对于错误,我们可以将用户重定向到我们的 404 页面(可能充满了双关语和 GIF 图像)
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* 404.html [L]
</IfModule>
首先,我们检查mod_rewrite
模块是否可用,然后我们可以打开它,如果找不到文件或目录,我们将把用户发送到我们的 404 页面。有趣的是,他们看到的页面内容将来自404.html
文件,而请求的 URL 将保持不变。
如果您不习惯处理.htaccess
文件,并且安装了 WordPress,那么有一个很棒的扩展可以为我们处理这些事情。
Nginx 重定向
如果您的服务器运行Nginx作为 Web 服务器,那么您可以在nginx.conf
文件中添加一个服务器块来处理这些重定向请求
server {
listen 80;
server_name old-website.com;
return 301 $scheme://new-website.com$request_uri;
}
我们再次使用 301 HTTP 响应,并且使用scheme
变量,我们将请求http://
或https://
,具体取决于原始网站使用的协议。最好仔细查看HTML5 Boilerplate nginx.conf,了解其他与 Nginx 相关事项的最佳实践。
Lighttpd 重定向
对于运行Lighttpd Web 服务器的那些服务器,您可以通过首先导入mod_redirect
模块并使用url.redirect
来进行重定向
server.modules = (
"mod_redirect"
)
$HTTP["host"] =~ "^(www\.)?old-website.com$" {
url.redirect = (
"^/(.*)$" => "http://www.new-website.com/$1",
)
}
PHP 重定向
使用 PHP,我们可以使用 header 函数,它非常直观。
<?php
header('Location: http://www.new-website.com');
exit;
?>
这必须在任何标记或任何其他类型的內容之前设置,但是有一个小问题。默认情况下,该函数会发送 302 重定向响应,它告诉所有人内容只是暂时移动了。考虑到我们的特定用例,我们需要将文件永久移动到我们的新网站,因此我们需要进行 301 重定向。
<?php
header('Location: http://www.new-website.com/', true, 301);
exit();
?>
上面可选的 true
参数将替换先前设置的标头,而末尾的 301 会将响应代码更改为正确的代码。
Ruby on Rails 重定向
在 Rails 项目 的任何控制器中,我们可以使用 redirect_to
和将 :status
选项设置为 :moved_permanently
来快速重定向到新网站。这样,我们便可以覆盖默认的 302 状态代码,并将其替换为永久移动。
class WelcomeController < ApplicationController
def index
redirect_to 'http://new-website.com', :status => :moved_permanently
end
end
在 Rails 4 中,我们可以通过在 routes.rb
文件中添加 redirect
来更轻松地处理这些请求,它会自动发送 301 响应。
get "/blog" => redirect("http://new-website.com")
或者,如果我们想将博客上的所有文章重定向到新网站上的帖子,我们可以用以下内容替换以上内容
get "/blog/:post" => redirect("http://new-website.com/blog/%{post}")
.NET 重定向
我以前从未使用过 .NET 框架编写过任何东西,但看起来微软的开发人员网络上有一些 清晰的文档。
Node.js 重定向
这是一个非常快速的本地设置,它解释了重定向如何在 Node 中工作。首先,我们包含 http
模块并创建一个新服务器,然后是 .writeHead()
方法。
var http = require("http");
http.createServer(function(req, res) {
res.writeHead(301,{Location: 'http://new-website.com'});
res.end();
}).listen(8888);
如果您创建一个名为 index.js
的新文件,并将上面的代码粘贴进去,然后在命令行中运行 node index.js
,您会发现该网站的本地版本将重定向到 new-website.com
。但要重定向 /blog
部分中的所有帖子,我们需要使用 Node 方便的 url
模块从请求中解析 URL。
var http = require("http");
var url = require("url");
http.createServer(function(req, res) {
var pathname = url.parse(req.url).pathname;
res.writeHead(301,{Location: 'http://new-website.com/' + pathname});
res.end();
}).listen(8888);
然后,我们可以使用 .writeHead()
函数将请求中的路径名附加到 URL 字符串的末尾。现在它将重定向到我们新网站上的相同路径。为 JavaScript 欢呼!
Flask 重定向
在 Flask 框架(位于 Python 之上)中,我们可以使用 redirect
函数简单地创建一个指向子页面的路由,同样,301 必须是在最后传递的选项,因为默认设置为 302。
@app.route('/notes/<page>')
def thing(page):
return redirect("http://www.new-website.com/blog/" + page, code=301)
如果您知道任何其他重定向网页的技巧,请在下面添加评论,我会用最新信息更新此帖子。
谢谢。
一个小细节,我认为“重定向 301 / http://www.new-website.com”是 mod_rewrite 的一部分,而不是 mod_redirect。
“虽然这听起来像是一部科幻警匪片的酷炫名字”——很有可能是布鲁斯·威利斯主演的!;)
“无限重定向循环器”
干得好,罗宾。清晰且全面。
嗯,
location.replace
和location.assign
是函数,因此您应该将 URL 放在括号中。不过,不错的综述。
很好!是我的错,不是罗宾的错。我曾经读过一篇帖子,上面列出了大约 100 种可以在 JavaScript 中重定向页面的方法,我想添加这些方法,但我找不到它,所以我只是在那里添加了一些。
你应该更频繁地使用 delicious,Chris :)
很棒的信息,现在我用它来为我的新网站进行 302 重定向。
很棒的文章,很高兴看到包含了这么多不同的架构。
此外,对这个惊人的 HR 加分,我不知道为什么我之前没有注意到,但这真是太美妙了。
对于那些感到被冷落了的 .NET 人员
Golang:
我一直都在寻找这个问题,我在他们健康结束的时候找到了它,非常感谢你的帮助。
好文章!
.htaccess
的问题是它很快就会变得非常混乱。如果您只需要一些简单的重定向,它非常棒,但是如果您还想强制执行 www 或非 www 怎么办?如果您想删除多余的斜杠或结尾斜杠并重定向怎么办?如果您想创建一些别名怎么办,例如:当我请求/fr/page
时,提供位于/languages/french/page
的文件?重定向和规范 URL 逻辑可能非常复杂,因为语法很隐晦,声明顺序很重要。
.htaccess
也用于其他几个目的,例如启用 gzip。因此,您将一堆不同的问题塞在一个文件中。如果您正在使用框架,那么所有请求都会通过
index.php
进行路由。那么为什么不将此复杂逻辑从.htaccess
中移出并将其放到您的主代码中呢?.htaccess
是一个服务器设置覆盖文件。它不是存放逻辑的好地方。逻辑应该放在您的代码中。例如,我使用 Laravel。我有一个
LinkResolver
类,专门负责重定向、别名和强制执行规范 URL 的逻辑。我维护一个单独的文件,该文件以 PHP 数组形式存储我的重定向,另一个文件用于别名。因为我将此逻辑放在了代码中,所以我可以编写自动化测试以确保它按预期工作。这使它变得健壮——而 Apache 的
mod_rewrite
就像巫术一样,正如 官方文档 所承认的那样。…因为语法很隐晦,并且声明顺序很重要。
胖乎乎的手指。
如果您不打算使用服务器重定向,您可能也应该在原始页面中包含一个显式链接。这将涵盖那些不支持
meta http-equiv
且未启用 JavaScript 的客户端。不知道重定向也可以使用 Node.js 和 RAILS 完成。感谢分享。
我使用重定向插件来迁移旧网站的页面
感谢你的信息。
Django 中的原理与 Flask 几乎相同
def my_view(request)
...
return redirect('/some/url/')
Helicon Ape(IIS 的 Apache .htaccess 和 .htpasswd 模拟器)不支持“重定向 301 /old /new”语法,导致 500 错误。它需要使用标志的 RewriteRule。
RewriteRule /some-page http://new-website.com/some-page [NC,R=301,L]
NC 代表 NoCase,R=301 表示我们不想重写,而是重定向,L 代表 Last,表示匹配到的最后一个 .htaccess 行并使用它。
一篇很棒的文章!之前我只知道一些网页重定向技巧,比如 `window.location="http://any-website.com";`。感谢 Robin Rendle 和 Chris Coyier 的这篇详细的文章。
不过要记住,并不是每个人都允许使用 Javascript,因此如果使用 Javascript,请确保有一个备用方法!
哎呀,刚看到 Stephen Thomas 在上面提到了这一点!对不起 Stephen!
最乐观的估计是禁用 Javascript 的用户不到 2%。我不确定我会牺牲这个功能。
除了上面的列表之外,Jekyll/Github 页面也有重定向功能。以下链接应该提供您实现相同目标所需的所有信息,
https://help.github.com/articles/redirects-on-github-pages/
这是关于网页重定向的最佳文章
非常感谢
在 IIS 中配置 HTTP 重定向,来自微软 Tech Net。
非常全面和透彻的文章。我想问一个问题:是否可以使用与单个网页相同的步骤来重定向整个网站?
不幸的是,并不那么简单(如果我错了,请纠正我,但我还没有看到任何针对整个网站的解决方案)。
……但是,看看 Chris 的这篇 旧文章。非常简单的解决方案。
很高兴您提出这个问题,让我学到了一些新东西;)
非常感谢 Robin,非常有用的文章!
您能否解释一下重定向如何反映在 Google 搜索结果中?
我的意思是,在新网站开发期间,互联网流量中是否存在一些差异或差距?
谢谢!
Robin 解释得很好,我只想补充几行,我一直使用 .net 框架,它在我的网站上表现得很好。
谢谢!
您好。我想问您一个问题。我不是网页开发人员,所以这些东西对我来说有点像希腊语。我想知道的是,是否有一种方法可以在一个网站重定向到另一个网站之前显示一条消息。例如,有一个现有的网站,http://www.example1.com,星期一我们将重定向到 http://www.example2.com,但是如果用户输入 http://www.example1.com,是否可以出现一条消息,内容类似于:感谢您访问 http://www.example1.com,您将被重定向到我们全新改进的网站 http://www.example2.com? 这在 WordPress 中是否很容易实现?您是否见过可以分享的示例?谢谢。
对于初学者来说,信息非常简单,但很有用。
非常全面。
Robin 做得很好。
您可以使用规范标签来重定向,从搜索引擎的角度来看。
网页重定向和规范化是两回事。重定向是说“你应该去其他地方”。规范化(在 SEO 术语中)让搜索引擎知道相同的内容可能由多个 URL 表示,并使用单个指定的 URL 而不是多个 URL。
这个方法真的很简单,但也很有趣,而且效果很好。感谢您分享它。我发现它很有用,信息量也很大。我只需要检查文件是否存在。当我搜索网络时,我还发现这篇文章 http://www.lionleaf.com/blog/how-to-redirect-using-php/ 也提供了相同的信息,但您的思路清晰,直接。您能告诉我如何在合适的 PHP 代码中实现它吗?
Rafiudeen Chozhan Kumarasamy 在文中介绍了如何在 Java 中实现。