如果您了解基本的HTTP请求 - 响应机制,那么's a lot mod_rewrite can do and very complex matching rules you can create, including chaining several rewrites, proxying requests to a completely different service or machine, returning specific HTTP status codes as responses, redirecting requests etc. It'非常强大并且可以用得很好 . 它不会自动使您的链接漂亮 .
# if the host doesn't start with www. then add it and redirect
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# if it cant find the image, try find the image on another domain
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)$ http://www.example.com/$1 [L]
你're most commonly seeing RewriteRules to simulate a virtual directory structure. But you'不是被迫没有创造力 . 您也可以使用 - 连字符进行分段或结构化 .
RewriteRule ^user-(\d+)$ show.php?what=user&id=$1
# └──────────────────────────────┘
# This could use `(\w+)` alternatively for user names instead of ids.
4 回答
要了解什么mod_rewrite,您首先需要了解Web服务器的工作原理 . Web服务器响应HTTP requests . 最基本级别的HTTP请求如下所示:
这是浏览器向Web服务器请求URL
/foo/bar.html
的简单请求 . 重要的是要强调它不请求文件,它只请求一些任意URL . 请求也可能如下所示:这与URL的请求一样有效,而且它显然与文件无关 .
Web服务器是一个侦听端口的应用程序,接受来自该端口的HTTP请求并返回响应 . Web服务器可以完全自由地以任何方式响应任何请求,以任何方式配置它以响应 . 此响应不是文件,它是HTTP响应,可能与任何磁盘上的物理文件有关,也可能没有 . Web服务器不一定是Apache,还有许多其他Web服务器,它们都只是持久运行并附加到响应HTTP请求的端口的程序 . 你可以自己写一个 . 本段旨在使您与URL直接等于文件的任何概念脱节,这对于理解非常重要 . :)
大多数Web服务器的默认配置是查找与硬盘上的URL匹配的文件 . 如果服务器的文档根目录设置为
/var/www
,则可能会查看文件/var/www/foo/bar.html
是否存在并提供服务(如果是) . 如果文件以".php"结尾,它将调用PHP解释器,然后返回结果 . 所有这些关联都是完全可配置的;一个文件不必与磁盘上的任何特定文件匹配以发生某些事情 .mod_rewrite是一种重写内部请求处理的方法 . 当Web服务器收到URL
/foo/bar
的请求时,您可以在Web服务器在磁盘上查找与其匹配的文件之前将该URL重写为其他内容 . 简单的例子:此规则表示每当请求匹配"/foo/bar"时,将其重写为"/foo/baz" . 然后将处理该请求,就好像已经请求
/foo/baz
一样 . 这可用于各种效果,例如:此规则匹配任何内容(
.*
)并捕获它((..)
),然后重写它以追加".html" . 换句话说,如果/foo/bar
是请求的URL,它将被处理,就像请求了/foo/bar.html
一样 . 有关正则表达式匹配,捕获和替换的更多信息,请参阅http://regular-expressions.info .另一个经常遇到的规则是:
这再次匹配任何内容并将其重写到文件index.php,并在
url
查询参数中附加最初请求的URL . 即,对于任何和所有请求进入,文件index.php被执行,该文件将有权访问$_GET['url']
中的原始请求,因此它可以用它做任何想做的事情 .主要是将这些重写规则放入Web服务器配置文件中 . Apache还允许您将它们放入文档根目录(即.php文件旁边)中名为
.htaccess
的文件中 .*如果主Apache配置文件允许;它是可选的,但通常是启用的 .
mod_rewrite没有做什么
mod_rewrite并没有神奇地使你的所有网址“漂亮” . 这是一个常见的误解 . 如果您的网站中有此链接:
mod_rewrite没有什么可以做的那么漂亮 . 为了使它成为一个漂亮的链接,你必须:
/my/pretty/link
的请求 .(人们可以结合使用mod_substitute来转换传出的HTML页面及其包含的链接 . 虽然这比仅仅更新HTML资源更省力 . )
如果您了解基本的HTTP请求 - 响应机制,那么's a lot mod_rewrite can do and very complex matching rules you can create, including chaining several rewrites, proxying requests to a completely different service or machine, returning specific HTTP status codes as responses, redirecting requests etc. It'非常强大并且可以用得很好 . 它不会自动使您的链接漂亮 .
有关所有可能的标志和选项,请参阅official documentation .
mod_rewrite的替代品
可以在不使用RewriteRules的情况下实现许多基本的虚拟URL方案 . Apache允许在没有
.php
扩展名的情况下调用PHP脚本,并使用虚拟PATH_INFO
参数 .使用PATH_INFO,Luke
如今AcceptPathInfo On经常被启用默认 . 这基本上允许
.php
和其他资源URL携带虚拟参数:现在这个
/virtual/path
在PHP中显示为$_SERVER["PATH_INFO"],您可以根据需要处理任何额外的参数 .这不像将Apache单独的输入路径段分配到
$1
,$2
,$3
并将它们作为不同的$_GET
变量传递给PHP那样方便 . 它只是用较少的配置工作来模拟"pretty URLs" .启用MultiViews以隐藏.php扩展名
在URL中避开
.php
"file extensions"的最简单选项是:由于匹配的基本名称,这为
/article
上的HTTP请求选择了article.php
. 这与上述PATH_INFO功能一起使用效果很好 . 所以你可以使用像http://example.com/article/virtual/title
这样的网址 . 如果您的传统Web应用程序具有多个PHP调用点/脚本,那么这是有意义的 .请注意,MultiViews具有不同/更广泛的用途 . 它会导致非常小的性能损失,因为Apache总是查找具有匹配基本名称的其他文件 . 它实际上意味着Content-Negotiation,因此浏览器在可用资源中获得最佳选择(例如
article.en.php
,article.fr.php
,article.jp.mp4
) .用于无扩展名.php脚本的SetType或SetHandler
对于其他文件方案,避免在URL中携带
.php
后缀的更直接的方法是configuring the PHP handler . 最简单的选项是通过.htaccess
覆盖默认的MIME /处理程序类型:这样您就可以将
article.php
脚本重命名为article
(不带扩展名),但仍将其作为PHP脚本处理 .现在,这可能会带来一些安全性和性能影响,因为现在所有无扩展文件都将通过PHP传输 . 因此,您也可以仅为单个文件设置此行为:
这在某种程度上取决于您的服务器设置和使用的PHP SAPI . 常见的替代方案包括
ForceType application/x-httpd-php
或AddHandler php5-script
.其他Apache重写方案
在其众多选项中,Apache提供了
mod_alias
功能 - 有时与mod_rewrite
的RewriteRules一样有效 . 请注意,大多数必须在<VirtualHost>
部分中设置,而不是在每个目录.htaccess
配置文件中 .ScriptAliasMatch主要用于CGI脚本,但也适用于PHP . 它允许regexp像任何
RewriteRule
一样 . 事实上,它可能是配置全能前控制器的最强大的选择 .简单的Alias也有一些简单的重写方案 .
甚至可以使用普通的ErrorDocument指令让PHP脚本处理虚拟路径 . 请注意,这是一个kludgy解决方法,但是,除了GET请求之外什么都禁止,并且根据定义泛滥error.log .
有关更多提示,请参阅http://httpd.apache.org/docs/2.2/urlmapping.html .
为了扩展deceze's answer,我想提供一些示例和一些其他mod_rewrite功能的解释 .
以下所有示例均假设您已在
.htaccess
文件中包含RewriteEngine On
.重写示例
让我们举个例子:
该规则分为4个部分:
RewriteRule
- 启动重写规则^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$
- 这被称为模式,但是我只是将它称为规则的左侧 - 你要重写的是什么blog/index.php?id=$1&title=$2
- 调用替换或重写规则的右侧 - 您想要重写的内容[NC,L,QSA]
是重写规则的标志,用逗号分隔,我稍后会详细解释上面的重写将允许您链接到类似
/blog/1/foo/
的东西,它实际上会加载/blog/index.php?id=1&title=foo
.规则的左侧
^
表示页面名称的开头 - 因此它将重写example.com/blog/...
但不会重写example.com/foo/blog/...
每组
(…)
括号表示一个正则表达式,我们可以将其捕获为规则右侧的变量 . 在这个例子中:第一组括号 -
([0-9]+)
- 匹配长度最小为1个字符且仅包含数字值(即0-9)的字符串 . 这可以通过规则右侧的$1
引用第二组括号匹配长度至少为1个字符的字符串,仅包含字母数字字符(AZ,az或0-9)或
-
或+
(注意+
使用反斜杠进行转义,因为没有转义它将会执行regex repetition character) . 这可以通过规则右侧的$2
引用?
表示前面的字符是可选的,所以在这种情况下/blog/1/foo/
和/blog/1/foo
都会重写到同一个地方$
表示这是结束了我们想要匹配的字符串标志
这些是在重写规则末尾的方括号中添加的选项,用于指定特定条件 . 同样,有很多不同的标志你可以在the documentation中阅读,但我将通过一些更常见的标志:
无案例标志意味着重写规则不区分大小写,因此对于上面的示例规则,这将意味着
/blog/1/foo/
和/BLOG/1/foo/
(或其任何变体)将匹配 .最后一个标志表示这是应该处理的最后一条规则 . 这意味着当且仅当此规则匹配时,才会在当前重写处理运行中评估其他规则 . 如果规则不匹配,则将照常按顺序尝试所有其他规则 . 如果未设置
L
标志,则以下所有规则将应用于重写的URL .从Apache 2.4开始,您也可以使用
[END]
标志 . 与它匹配的规则将完全终止进一步的别名/重写处理 . (而[L]
标志通常可以触发第二轮,例如重写到子目录或从子目录重写时 . )查询字符串append标志允许我们将额外的变量传递给指定的URL,该URL将被添加到原始的get参数中 . 对于我们的示例,这意味着
/blog/1/foo/?comments=15
之类的内容会加载/blog/index.php?id=1&title=foo&comments=15
这个标志不是我在上面的例子中使用过的,但是我认为值得一提 . 这允许您指定http重定向,并带有包含状态代码的选项(例如
R=301
) . 例如,如果您想在/ myblog / to / blog /上执行301重定向,您只需编写如下规则:重写条件
Rewrite conditions使重写功能更强大,允许您为更具体的情况指定重写 . 您可以在the documentation中阅读很多条件,但我会介绍几个常见示例并解释它们:
这是一种非常常见的做法,它会在您的域前添加
www.
(如果它不存在)并执行301重定向 . 例如,加载http://example.com/blog/
会将您重定向到http://www.example.com/blog/
这稍微不太常见,但如果文件名是服务器上存在的目录或文件,则这是一个不执行的规则的好例子 .
%{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
将仅对文件扩展名为jpg,jpeg,gif或png(不区分大小写)的文件执行重写 .%{REQUEST_FILENAME} !-f
将检查当前服务器上是否存在该文件,如果不存在则仅执行重写%{REQUEST_FILENAME} !-d
将检查当前服务器上是否存在该文件,如果不存在则仅执行重写重写将尝试在另一个域上加载相同的文件
参考文献
Stack Overflow还有许多其他很好的资源可供使用:
Serverfault: Everything you ever wanted to know about mod_rewrite
(请记住删除.htaccess用法的^ / pattern前缀中的斜杠 . )
在Hidden features of mod_rewrite中执行's and Dont' .
查看我们的most popular mod-rewrite问题和答案 .
Apache redirecting and remapping指南 .
AskApache ultimate .htaccess guide
和mod-rewrite tag wiki references .
而且新人友好的正则表达式概述甚至:
我们的regex tag wiki用于语法概要 .
和短Apache regex summary .
其他regexp.info易于理解的基础知识 .
Oft-used占位符
.*
匹配任何内容,甚至是空字符串 . 您不希望在任何地方使用此模式,但通常在最后一个回退规则中使用 .[^/]+
更常用于路径段 . 除了正斜杠之外,它匹配任何东西 .\d+
仅匹配数字字符串 .\w+
匹配字母数字字符 . 它基本上是[A-Za-z0-9_]
的简写 .[\w\-]+
for "slug"-型路径段,使用字母,数字,短划线-
和_
[\w\-.,]+
添加句点和逗号 . 首选[…]
charclasses中的转义\-
破折号 .\.
表示文字句号 . 否则[…]
之外的.
是任何符号的占位符 .这些占位符中的每一个通常都包含在
(…)
括号中作为捕获组 . 并且整个模式通常在^………$
开始结束标记 . 引用"patterns"是可选的 .RewriteRules
以下示例以PHP为中心,稍微增量,更容易适应类似情况 . 它们只是摘要,通常链接到更多变化或详细的问答 .
静态映射/联系,/ about
将一些页面名称缩短为内部文件方案是最简单的:
数字标识符/对象/ 123
向现有PHP脚本引入像
http://example.com/article/531
这样的快捷方式也很容易 . 数字占位符只能重新映射到$_GET
参数:Slug风格的占位符/ article / with-some-title-slug
您可以轻松扩展该规则以允许
/article/title-string
占位符:请注意你的脚本 must 能够(或适应)将这些 Headers 映射回数据库ID . 仅凭RewriteRules无法凭空创建或猜测信息 .
带有数字前缀/可读/ 123加 Headers 的S ..
因此,您经常会看到在实践中使用的混合
/article/529-title-slug
路径:现在你可以跳过传递
title=$2
,因为你的脚本通常依赖于数据库id .-title-slug
已成为任意URL装饰 .与替代清单/ foo / ... / bar / ... / baz / ...的统一性
如果您有多个虚拟页面路径的类似规则,则可以使用
|
备用列表进行匹配和压缩 . 再次将它们重新分配给内部GET参数:如果这太复杂,你可以把它们分成单独的
RewriteRule
.将相关URL调度到不同的后端/ date / SWITCH / backend
替代列表的更实际用途是将请求路径映射到不同的脚本 . 例如,根据日期为较旧和较新的Web应用程序提供统一的URL:
这只是将2009-2011帖子重新映射到一个脚本上,而将所有其他年份隐式重新映射到另一个脚本 . 请注意首先出现的更具体的规则 . 每个脚本可能使用不同的GET参数 .
除了/ path slashes / user-123-name之外的其他分隔符
你're most commonly seeing RewriteRules to simulate a virtual directory structure. But you'不是被迫没有创造力 . 您也可以使用
-
连字符进行分段或结构化 .对于common / wiki:section:Page_Name方案:
偶尔,它甚至适用于在同一规则中在
/
-delimiters和:
或.
之间交替 . 或者再次使用两个RewriteRules将变体映射到不同的脚本 .可选尾随/斜杠/目录= /目录/
选择目录样式的路径时,可以使用和不使用final /
现在它处理
http://example.com/blog/123
和/blog/123/
. 并且/?$方法很容易附加到任何其他RewriteRule上 .虚拟路径的灵活段 . * / . * / . * / . *
您将遇到的大多数规则将约束的
/…/
资源路径段映射到单个GET参数 . 但是有些脚本handle a variable number of options . Apache regexp引擎不允许任意选择任意数量的引擎 . 但您可以轻松地将其扩展为规则块:如果最多需要五个路径段,请将此方案复制到五个规则中 . 您当然可以使用更具体的
[^/]+
占位符 . 这里的顺序并不重要,因为它们都没有重叠 . 因此,首先使用最常用的路径是可以的 .或者,您可以在此处通过
?p[]=$1&p[]=$2&p[]=3
查询字符串使用PHP数组参数 - 如果您的脚本仅仅预先分割它们 . (虽然使用全能规则更常见,但让脚本本身将段扩展到REQUEST_URI之外 . )另见:How do I transform my URL path segments into query string key-value pairs?
可选段前缀/ opt?/.*
常见的变体是在规则中具有可选前缀 . 如果您有静态字符串或更多受约束的占位符,这通常是有意义的:
现在更复杂的模式
(?:/([^/])+)?
只包含一个非捕获(?:…)
组,并使其成为可选)?
. 包含的占位符([^/]+)
将是替换模式$2
,但如果没有中间/…/
路径则为空 .捕获余数/前缀/ 123-capture / ... / * / ......无论如何......
如前所述,您通常不需要过于通用的重写模式 . 然而,有时将静态和特定比较与
.*
结合起来是有意义的 .这可选任何
/…/…/…
尾随路径段 . 然后当然需要处理脚本将它们拆分,并且可变地提取参数本身(这是Web-"MVC"框架所做的) .尾随文件“extensions”/old/path.HTML
网址实际上没有文件扩展名 . 这是整个参考文献的内容(= URL是虚拟定位器,不一定是直接文件系统映像) . 但是,如果之前有1:1的文件映射,则可以制定更简单的规则:
其他常见用途是将过时的
.html
路径重新映射到较新的.php
处理程序,或仅为单个(实际/实际)文件别名目录名称 .乒乓(重定向和重写一致)/ugly.html←→/漂亮
因此,在某些时候,您正在重写HTML页面以仅携带漂亮的链接,如outlined by deceze . 与此同时,您仍然会收到旧路径的请求,有时甚至会收到书签 . 作为解决方法,您可以使用乒乓浏览器来显示/ Build 新URL .
这种常见技巧涉及在传入的URL遵循过时/丑陋的命名方案时发送30x /位置重定向 . 然后,浏览器将重新请求新的/漂亮的URL,然后将其重新编写(仅在内部)到原始位置或新位置 .
请注意此示例如何仅使用
[END]
而不是[L]
安全地交替 . 对于较旧的Apache 2.2版本,您可以使用其他解决方法,除了还重新映射查询字符串参数,例如:Redirect ugly to pretty URL, remap back to the ugly path, without infinite loops空间␣在模式/这个
它在浏览器地址栏中并不漂亮,但您可以在URL中使用空格 . 对于重写模式,请使用反斜杠转义的
\␣
空格 . 其他只是"
- 引用整个模式或替换:客户端使用
+
或%20
序列化URL以获取空格 . 然而在RewriteRules中,它们用所有相对路径段的文字字符进行解释 .经常重复:
Catch-all用于中央调度程序/前端控制器脚本
这通常由PHP框架或WebCMS /门户脚本使用 . 然后使用
$_SERVER["REQUEST_URI"]
在PHP中处理实际的路径拆分 . 因此,从概念上讲,它几乎与URL处理相反"per mod_rewrite" . (只需使用FallBackResource代替 . )删除www . 来自主机名
请注意,这不会复制查询字符串等 .
也可以看看:
·URL rewriting for different protocols in .htaccess
·Generic htaccess redirect www to non-www
·.htaccess - how to force "www." in a generic way?
请注意,RewriteCond / RewriteRule组合可能更复杂,匹配(
%1
和$1
)甚至在两个方向上相互作用:Apache手册 - mod_rewrite简介,版权所有2015 The Apache Software Foundation,AL-2.0
重定向到HTTPS://
另见:https://wiki.apache.org/httpd/RewriteHTTPToHTTPS
“删除”PHP扩展
另见:Removing the .php extension with mod_rewrite
将旧的.html路径别名为.php脚本
见:http://httpd.apache.org/docs/2.4/rewrite/remapping.html#backward-compatibility
从“/ page”等网址重写为“/index.php/page”等脚本
见mod_rewrite, php and the .htaccess file
将子域重定向到文件夹
见How can i get my htaccess to work (subdomains)?
普遍存在.htaccess陷阱
现在带上一粒盐 . 并非所有建议都可以推广到所有情境 . 这只是一个众所周知的和一些不明显的绊脚石的简单总结:
启用mod_rewrite和.htaccess
要在每个目录配置文件中实际使用RewriteRules,您必须:
检查您的服务器是否AllowOverride All enabled . 否则,您的每个目录
.htaccess
指令将被忽略,并且RewriteRules将不起作用 .显然have mod_rewrite enabled在您的
httpd.conf
模块部分 .使用
RewriteEngine On
前置每个规则列表 . 虽然mod_rewrite在<VirtualHost>
和<Directory>
部分中是隐式激活的,但每个目录的.htaccess
文件需要单独召唤它 .前导斜杠^ /将不匹配
您不应该使用
^/
正常启动.htaccess
RewriteRule模式:这在旧教程中经常出现 . 它曾经是古老的Apache 1.x版本的正确 . 现在,请求路径在
.htaccess
RewriteRules中方便地完全 directory-relative . 只需离开领先/
.·请注意,在
<VirtualHost>
部分中,前导斜杠仍然正确 . 这就是为什么你经常看到它^/?
为规则奇偶校验可选 .·或者当使用
RewriteCond %{REQUEST_URI}
时,你仍然匹配领先的/
.·参见Webmaster.SE: When is the leading slash (/) needed in mod_rewrite patterns?
<IfModule *>包装器开始!
您可能在许多示例中看到了这一点:
在
<VirtualHost>
部分确实有意义 - 如果它与另一个后备选项结合使用,例如ScriptAliasMatch . (但没有人这样做过) .它通常分布在具有许多开源项目的默认
.htaccess
规则集中 . 它只是意味着后备,并保持"ugly" URL默认工作 .但是你 don't want 通常在你自己的
.htaccess
文件中 .首先,mod_rewrite不会随机脱离 . (如果确实如此,你会遇到更大的问题) .
如果真的被禁用了,你的RewriteRules仍然无法正常工作 .
这是为了防止HTTP
500
错误 . 它通常会完成的工作是用HTTP404
错误为您的用户提供支持 . (如果你考虑一下,那就不那么友好了 . )实际上它只是抑制了更有用的日志条目或服务器通知邮件 . 关于为什么你的RewriteRules永远不会工作,你应该 none the wiser .
除非需要,否则不要使用RewriteBase
许多复制粘贴示例包含
RewriteBase /
指令 . 无论如何,这恰好是隐含的默认值 . 因此,您不必为虚拟主机重写方案提供解决方案,并为某些共享主机提供错误的DOCUMENT_ROOT路径 .在较深的子目录中使用单个Web应用程序是有意义的 . 在这种情况下,它可以缩短RewriteRule模式 . 通常,最好在每个目录的规则集中使用相对路径说明符 .
另见How does RewriteBase work in .htaccess
虚拟路径重叠时禁用MultiView
URL重写主要用于支持虚拟传入路径 . 通常,您只有一个调度程序脚本(
index.php
)或一些单独的处理程序(articles.php
,blog.php
,wiki.php
,...) . 该后者might clash具有类似的虚拟RewriteRule路径 .例如,对
/article/123
的请求可以隐式地使用/123
PATH_INFO映射到article.php
. 你要么必须保护你的规则,然后使用普通的RewriteCond
!-f
!-d
,和/或禁用PATH_INFO支持,或者只是禁用Options -MultiViews
.这并不是说你总是必须这样做 . 内容协商只是虚拟资源的自动化 .
订购很重要
如果你没有习惯性地预防
[L]
标志,那么请参见Everything you ever wanted to know about mod_rewrite,但这是一个精通你的计划 . 您_1110480_从一个规则到另一个规则的虚拟路径,直到它到达实际的目标处理程序 .您仍然希望在早期规则中拥有最具体的规则(固定字符串
/forum/…
模式或更严格的占位符[^/.]+
) . 通用的slurp-all规则(.*
)最好留给后者 . (一个例外是RewriteCond -f/-d
guard作为主要块 . )样式表和图像停止工作
当您引入虚拟目录结构
/blog/article/123
时,这会影响HTML中的相对资源引用(例如<img src=mouse.png>
) . 哪个可以解决:仅使用服务器绝对引用
href="/old.html"
或src="/logo.png"
通常只需将
<base href="/index">
添加到HTML<head>
部分即可 . 这隐含地重新引用了之前的相对引用 .您可以选择制作更多RewriteRules以将
.css
或.png
路径重新绑定到其原始位置 . 但这既不需要,也不会引发额外的重定向并妨碍缓存 .另见:CSS, JS and images do not display with pretty url
RewriteConds只掩盖一个RewriteRule
一个常见的误解是RewriteCond会阻止多个RewriteRules(因为它们在视觉上排列在一起):
它默认不是 . 您可以使用
[S=2]
标志chain them . 否则你将不得不重复它们 . 虽然有时您可以制定一个"inverted"主要规则来[END]早期重写处理 .QUERY_STRING免于RewriteRules
您无法匹配
RewriteRule index.php\?x=y
,因为mod_rewrite只比较默认情况下的相对路径 . 您可以通过以下方式单独匹配它们:另见How can I match query string variables with mod_rewrite?
.htaccess与<VirtualHost>
如果你在每个目录的配置文件中使用RewriteRules,那么担心正则表达式的性能是毫无意义的 . 与使用通用路由框架的PHP进程相比,Apache保留编译的PCRE模式的时间更长 . 但是,对于高流量站点,您应该考虑将规则集移动到vhost服务器配置中,一旦经过战斗测试 .
在这种情况下,更喜欢可选的
^/?
目录分隔符前缀 . 这允许在PerDir和服务器配置文件之间自由移动RewriteRules .每当某些东西不起作用时
不要烦恼 .
通常你可以通过查看
error.log
和access.log
来弄清楚RewriteRule是如何行为不端的 . 关联访问时间以查看最初进入的请求路径以及Apache无法解析的路径/文件(错误404/500) .这并不能告诉你哪个RewriteRule是罪魁祸首 . 但是像
/docroot/21-.itle?index.php
这样无法进入的最终路径可能会放弃进一步检查的地方 . 否则禁用规则,直到获得一些可预测的路径 .见Apache RewriteLog docs . 对于调试,您可以在vhost部分中启用它:
这会产生每个规则如何修改传入请求路径的详细摘要:
这有助于缩小过于通用的规则和正则表达式错误 .
也可以看看:
·.htaccess not working (mod_rewrite)
·Tips for debugging .htaccess rewrite rules
您可能知道,Stack Overflow非常适合在mod_rewrite上提问 . 通过包括先前的研究和尝试(避免多余的答案),使它们成为on-topic,展示基本的理解,以及:
包括输入URL的完整示例,错误重写的目标路径,真实的目录结构 .
完整的RewriteRule设置,但也挑出假定的有缺陷的一个 .
Apache和PHP版本,操作系统类型,文件系统,DOCUMENT_ROOT和PHP
$_SERVER
环境,如果它与参数不匹配有关 .摘自
access.log
和error.log
以验证现有规则解决的问题 . 更好的是,rewrite.log
摘要 .这样可以更快,更准确地回答问题,并使其对其他人更有用 .
评论您的.htaccess
如果您从某处复制示例,请注意包含
# comment and origin link
. 虽然省略归属只是不礼貌,但以后往往会伤害维护 . 记录任何代码或教程源 . 特别是在没有逆转的情况下,你应该更感兴趣的是不要像魔术黑盒一样对待它们 .这不是“SEO”-URLs
免责声明:只是一个宠儿小便 . 您经常会听到称为"SEO"链接的漂亮URL重写方案 . 虽然这对于谷歌搜索示例很有用,但这是一个过时的用词不当 .
没有现代搜索引擎在路径段中确实受到
.html
和.php
的干扰,或者?id=123
查询字符串 . 旧的搜索引擎,例如AltaVista,确实避免了抓取具有潜在暧昧访问路径的网站 . 现代爬虫通常甚至渴望获得深层网络资源 .什么"pretty" URL应该在概念上用于制作网站 user-friendly .
具有可读和明显的资源方案 .
确保URL是长期存在的(AKA permalinks) .
通过
/common/tree/nesting
提供可发现性 .但是,不要牺牲符合性的独特要求 .
工具
有大量的在线工具可以为大多数GET参数化URL生成RewriteRules:
http://www.generateit.net/mod-rewrite/index.php
http://www.ipdistance.com/mod_rewrite.php
http://webtools.live2support.com/misc_rewrite.php
通常只输出
[^/]+
通用占位符,但可能足够琐碎的网站 .