在Apache中重定向,更改URL或将HTTP重定向到HTTPS – 您想要知道的关于Mod_Rewrite规则的所有内容,但不敢问

这是关于Apache的mod_rewrite 的规范性问题

更改请求URL或将用户重定向到与他们最初请求的URL不同的URL是使用mod_rewrite完成的。这包括诸如:

  • 将HTTP更改为HTTPS(或其他方式)
  • 将请求更改为不存在的页面以替换新的替换。
  • 修改URL格式(例如?id = 3433到/ id / 3433)
  • 基于推荐人基于浏览器呈现不同的页面,基于月球和太阳下的任何可能情况。
  • 任何你想要搞乱URL的东西

你曾经想知道的关于Mod_Rewrite规则的所有内容,但都不敢问!

我怎样才能成为编写mod_rewrite规则的专家?

  • mod_rewrite规则的基本格式和结构是什么?
  • 我需要掌握哪些正则表达式的形式/风格?
  • 编写重写规则时最常见的错误/陷阱是什么?
  • 什么是测试和验证mod_rewrite规则的好方法?
  • 是否有我应该知道的mod_rewrite规则的SEO或性能影响?
  • 有没有常见的情况下mod_rewrite可能看起来像工作的正确工具,但不是?
  • 什么是常见的例子?

一个地方来测试你的规则

htaccess的测试网站是玩弄你的规则,并测试他们的好地方。它甚至显示调试输出,所以你可以看到什么匹配,什么没有。

答案


mod_rewrite语法顺序

mod_rewrite有一些影响处理的特定排序规则。在任何事情完成之前,RewriteEngine On需要给出指令,因为这会启用mod_rewrite处理。这应该在任何其他重写指令之前。

RewriteCond前面RewriteRule使得一条规则受制于条件。以下任何RewriteRules将被处理,就好像它们不受条件限制。

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html

在这种简单的情况下,如果HTTP引用来自serverfault.com,则将博客请求重定向到特殊的服务器默认页面(我们只是特别的)。但是,如果上面的块有一个额外的RewriteRule行:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg         $/blog/$1.sf.jpg

所有的.jpg文件都会转到特殊的服务器默认页面,而不仅仅是那些带有指示来自这里的引用链接的页面。这显然不是这些规则如何编写的意图。它可以用多个RewriteCond规则完成:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

但可能应该用一些更复杂的替换语法来完成。

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

更复杂的RewriteRule包含处理条件。最后一个括号,(html|jpg)告诉RewriteRule匹配html或者jpg,并且在重写的字符串中将匹配的字符串表示为$ 2。这在逻辑上与前面的块相同,有两个RewriteCond / RewriteRule对,它只是在两行而不是四行。

多个RewriteCond行被隐式地进行了与运算,并且可以进行明确的或运算。处理来自ServerFault和超级用户的引用(显式OR):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)    [OR]
RewriteCond %{HTTP_REFERER}                ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

使用Chrome浏览器提供ServerFault引用页面(隐式AND):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT}             ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteBase也是顺序特定的,因为它指定了下面的RewriteRule指令如何处理它们的处理。它在.htaccess文件中非常有用。如果使用,它应该是.htaccess文件中“RewriteEngine on”下的第一个指令。以这个例子:

RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

这告诉mod_rewrite它目前正在处理的这个特定的URL是通过http://example.com/blog/而不是物理目录路径(/ home / $ Username / public_html / blog)得到的,并相应地对待它。因此,RewriteRule认为它的字符串开始位于URL中的“/ blog”之后。这是用两种不同的方式写的。一个用RewriteBase,另一个没有:

RewriteEngine On

##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER}                                   ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg)     $1.sf.$2

##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

正如你所看到的,RewriteBase允许重写规则利用网站的内容路径而不是网络服务器,这可以使编辑这些文件的人更容易理解。此外,他们可以使指令更短,具有美学吸引力。


RewriteRule匹配语法

RewriteRule本身具有用于匹配字符串的复杂语法。我会在另一部分介绍标志(例如[PT])。因为系统管理员比阅读手册页更多地学习示例,所以我会举例说明他们的工作。

RewriteRule ^/blog/(.*)$    /newblog/$1

所述.*构建体的任何单个字符匹配(.)零次或多次(*)。将它括在圆括号中告诉它提供匹配的字符串作为$ 1变量。

RewriteRule ^/blog/.*/(.*)$  /newblog/$1

在这种情况下,第一个*不包含在parens中,因此不会提供给重写的字符串。此规则将删除新博客网站上的目录级别。(/blog/2009/sample.html变成/newblog/sample.html)。

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$2

在这种情况下,第一个括号表达式将设置一个匹配组。这变成$ 1,这是不需要的,因此不会在重写的字符串中使用。

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$1/$2

在这种情况下,我们在重写的字符串中使用$ 1。

RewriteRule ^/blog/(20[0-9][0-9])/(.*)$   /newblog/$1/$2

此规则使用指定字符范围的特殊括号语法。[0-9]与数字0到9匹配。该特定规则将处理从2000年到2099年的年份。

RewriteRule ^/blog/(20[0-9]{2})/(.*)$  /newblog/$1/$2

这和前面的规则完全相同,但是{2}部分告诉它匹配前一个字符(本例中为括号表达式)两次。

RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html   /newblog/$1/$2.shtml

这种情况将匹配第二个匹配表达式中的任何小写字母,并尽可能多地匹配它。该\.构造告诉它将该时期视为一个实际时期,而不是前面例子中的特殊特征。不过,如果文件名中有破折号,它会中断。

RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html  /newblog/$1/$2.shtml

这会在文件中使用破折号文件名。但是,正如-括号表达式中的特殊字符一样,它必须是表达式中的第一个字符。

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

此版本用文字,数字或文件名中的字符捕捉任何文件-名。这是如何在括号表达式中指定多个字符集。


重写规则标志

重写规则上的标志有许多特殊的含义和用例

RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html  /newblog/$1/$2.shtml  [L]

该标志是[L]上述表达式的结尾。可以使用多个标志,用逗号分隔。链接的文档描述了每一个,但是无论如何他们在这里:

L =最后。一旦匹配,就停止处理RewriteRules。订单数!
C =链。继续处理下一个RewriteRule。如果这个规则不匹配,那么下一个规则将不会被执行。稍后再说。
E =设置环境变量。Apache具有各种可能影响Web服务器行为的环境变量。
F =禁止。如果此规则匹配,则返回403-Forbidden错误。
G =走了。如果此规则匹配,则返回410-Gone错误。
H =处理程序。强制将请求处理为指定的MIME类型。
N =下一步。强制规则重新开始并重新匹配。小心!可能导致循环。
NC =无案例。允许jpg匹配JPG和JPG。
NE =没有逃脱。防止将特殊字符(。?#&等)重写为它们的十六进制等价物。
NS =没有子请求。如果您使用的是服务器端包含,这将阻止与包含文件匹配。
P =代理。强制规则由mod_proxy处理。透明地提供来自其他服务器的内容,因为您的Web服务器将其提供并重新提供。这是一个危险的标志,因为写得不好的将会把你的网络服务器变成一个开放的代理服务器,这很糟糕。
PT =通过。考虑RewriteRule匹配中的别名语句。
QSA = QSA出现。当原始字符串包含查询(http://example.com/thing?asp=foo)将原始查询字符串追加到重写的字符串中。通常它会被丢弃。对于动态内容很重要。
R =重定向。提供HTTP重定向到指定的URL。也可以提供精确的重定向代码[R = 303]。非常相似RedirectMatch,这是更快,应尽可能使用。
S =跳过。跳过这条规则。
T =类型。指定返回内容的MIME类型。与AddType指令非常相似。

你知道我是如何说RewriteCond适用于唯一的一条规则吗?那么,你可以通过链接来解决这个问题。

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html     [C]
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

因为第一个RewriteRule有链标志,所以第二个重写规则将在第一个重写规则执行时执行,这是前一个RewriteCond规则匹配的时候。如果Apache正则表达式让你的大脑受到伤害,那么方便。但是,从优化的角度来看,我在第一部分中指出的全合一方法更快。

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

这可以通过标志来简化:

RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html   /newblog/$1/$2.shtml   [NC]

此外,一些标志也适用于RewriteCond。值得注意的是,NoCase。

RewriteCond %{HTTP_REFERER}        ^https?://serverfault\.com(/|$)     [NC]

将匹配“ServerFault.com”

添加评论

友情链接:蝴蝶教程