4

我正在使用下面的代码来重写一些 URL:

RewriteEngine On
Options +FollowSymlinks
RewriteBase /
RewriteRule ^New_Hampshire/[a-zA-Z0-9_+\-\s]*\.html$ NH/

请记住,下面还有这条规则..

RewriteRule ^([a-zA-Z]{2})/ state.php?state=$1 [L]

现在,我想要实现的是,如果有人去例如:

www.mydomain.com/New_Hampshire/index.html

我希望位置栏显示:

www.mydomain.com/NH/

通常我可以通过[R]在最后使用标志来实现这一点,但是在这种情况下它不起作用,我猜这可能与次要规则有关。

这可能吗?

另外,我该如何更改它以便它也重定向:

www.mydomain.com/New_Hampshire/

如您所见,上面不包含index.html参考。

最后,如果我想进行这些301重定向,我会做类似的事情吗?

RewriteRule ^New_Hampshire/[a-zA-Z0-9_+\-\s]*\.html$ NH/ [R=301]
4

1 回答 1

3

您需要了解 URL 重写(在您的情况下由 Apache 的 mod_rewrite 实现)和重定向之间的区别,这是 HTTP 规范的一部分,通过向客户端(浏览器)发送标准 HTTP 标头和状态代码来实现。

通过 URL 重写,当 Web 服务器处理请求时,您可以选择将客户端发送的请求 URL 映射到由不同本地路径表示的本地资源。这样做是出于各种原因,例如能够向用户呈现干净和简短的 URL、隐藏服务器上资源的内部结构、保护某些资源等。

浏览器通常不知道服务器重写了 URL(除非有其他指示),并且仍会在地址栏中显示原始请求的 URL。在客户端不知道的情况下,无法远程操作客户端请求的 URL。

另一方面,HTTP 重定向是 HTTP 规范的一部分,是一种告诉客户端请求的 URL 可以在不同位置找到的方法。Web 服务器通过发送带有重定向 URL 的“Location”标头和告诉客户端发生了什么的 HTTP 状态代码来执行此操作。有几个 30x 状态码,最常用的是 301 用于告诉客户端该资源已永久移动并且应该从现在开始由新 URL 处理,以及 302 用于告诉浏览器该资源已找到但暂时驻留在一个新的 URL 下(当您在规则中指定 R 标志时,Apache 的实现默认使用 302)。

客户端将收到带有新位置和状态代码的 HTTP 响应,并向新 URL 发出新的 HTTP 请求。如果这是主请求(即不是对图像或脚本等资源的子请求),它还将替换地址栏中的位置。

http://httpd.apache.org/docs/current/rewrite/flags.html#flag_r

请注意,Apache 的文档建议将 L 标志与重定向标志一起使用(例如 [R, L] 或 [R=301, L]),否则您可能会得到意想不到的结果(因为它将继续处理以下规则)。这可能是您的 R 标志不起作用的原因。

所以,你可以做这样的事情(只是一个例子):

RewriteRule ^New_Hampshire.* NH/ [R=301, L]

这会将客户端从任何/New_Hampshire 前缀(带或不带 *.html)URL 重定向到 NH/ 并更改地址栏。

然后是下一条规则:

RewriteRule ^NH/? state.php?state=NH [L]

或更通用:

RewriteRule ^([a-zA-Z]{2})/? state.php?state=$1 [L]

这将捕获 NH(或其他状态)URL 并将其重写为正确的实际资源 (state.php)。

但是,这只是向您展示规则的示例。您可能需要处理第一条规则中的逻辑。因为需要将完整的州名 (New_Hampshire) 映射到快捷方式 (NH),除非您想为每个州编写规则。

于 2012-11-22T14:04:24.203 回答