# 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/ [L]
要了解 mod_rewrite 是什么,您首先需要了解 Web 服务器的工作原理。 Web 服务器响应 HTTP 请求。最基本级别的 HTTP 请求如下所示:
GET /foo/bar.html HTTP/1.1
这是浏览器向 Web 服务器请求 URL/foo/bar.html 的简单请求。需要强调的是,它并不请求文件,它只是请求一些任意的 URL。该请求也可能如下所示:
GET /foo/bar?baz=42 HTTP/1.1
这与 URL 请求一样有效,而且显然与文件无关。
Web 服务器是一个侦听端口的应用程序,接受来自该端口的 HTTP 请求并返回响应。 Web 服务器完全可以自由地以它认为合适的任何方式响应任何请求/以您配置它响应的任何方式响应。此响应不是一个文件,而是一个 HTTP 响应,它可能与任何磁盘上的物理文件有任何关系,也可能没有任何关系。 Web 服务器不一定是 Apache,还有许多其他 Web 服务器,它们都只是持久运行并附加到响应 HTTP 请求的端口的程序。你可以自己写一个。本段的目的是让您摆脱 URL 直接等于文件的任何观念,理解这一点非常重要。 :)
大多数 Web 服务器的默认配置是在硬盘上查找与 URL 匹配的文件。如果服务器的文档根设置为/var/www,它可能会查找文件/var/www/foo/bar. html 存在,如果存在则提供它。如果文件以“.php”结尾,它将调用 PHP 解释器并返回结果。所有这些关联都是完全可配置的;文件不必以“.php”结尾,Web 服务器即可通过 PHP 解释器运行该文件,并且 URL 不必与磁盘上的任何特定文件匹配才能发生某些事情。
mod_rewrite 是一种重写内部请求处理的方法。当 Web 服务器收到对 URL /foo/bar 的请求时,您可以将该 URL 重写为其他内容,然后 Web 服务器会在磁盘上查找匹配的文件它。简单的例子:
为了扩展deceze的答案,我想提供一些示例和一些其他 mod_rewrite 功能的解释。 p>
以下所有示例均假设您已在
.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/博客/...
(…)
括号代表一个正则表达式,我们可以将其捕获为规则右侧的变量。在这个例子中:([0-9]+)
- 匹配长度至少为 1 个字符且仅包含数字值(即 0-9)的字符串。这可以通过规则右侧的$1
引用-
或+ code> (注意
+
用反斜杠转义,因为如果不转义它,这将作为 正则表达式重复字符)。这可以通过规则右侧的$2
引用?
表示前面的字符是可选的,因此在本例中/blog/1/foo/
和/blog/1/foo
code> 将重写到同一位置$
表示这是我们要匹配的字符串的结尾标志
这些选项添加在重写规则末尾的方括号中,用于指定某些条件。同样,您可以在文档中阅读许多不同的标志,但我将介绍一些更常见的标志:
无大小写标志意味着重写规则不区分大小写,因此对于上面的示例规则,这意味着
/blog/1/foo/
和/BLOG/1/ foo/
(或其任何变体)将被匹配。最后一个标志表明这是应该处理的最后一条规则。这意味着当且仅当该规则匹配时,在当前重写处理运行中不会评估进一步的规则。如果规则不匹配,则将照常尝试所有其他规则。如果您不设置
L
标志,则随后的所有规则都将应用于重写的 URL。自 Apache 2.4 起,您还可以使用
[END]
标志。与之匹配的规则将完全终止进一步的别名/重写处理。 (而[L]
标志通常会触发第二轮,例如在重写子目录或重写子目录时。)查询字符串追加标志允许我们将额外的变量传递到指定的 URL,这些变量将添加到原始的 get 参数中。对于我们的示例,这意味着像
/blog/1/foo/?comments=15
这样的内容将加载/blog/index.php?id=1&title=foo&comments=15
这个标志不是我在上面的示例中使用的标志,但我认为值得一提。这允许您指定 http 重定向,并可以选择包含状态代码(例如
R=301
)。例如,如果您想在 /myblog/ 上执行 301 重定向到 /blog/,您只需编写如下规则:重写条件
重写条件使重写更加强大,允许您指定针对更具体情况的重写。您可以在文档中阅读很多条件>,但我将介绍一些常见示例并对其进行解释:
这是一种非常常见的做法,它将在您的域名前面添加
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
将检查当前服务器上是否存在该文件,如果不存在则执行重写要了解 mod_rewrite 是什么,您首先需要了解 Web 服务器的工作原理。 Web 服务器响应 HTTP 请求。最基本级别的 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 解释器并返回结果。所有这些关联都是完全可配置的;文件不必以“.php”结尾,Web 服务器即可通过 PHP 解释器运行该文件,并且 URL 不必与磁盘上的任何特定文件匹配才能发生某些事情。mod_rewrite 是一种重写内部请求处理的方法。当 Web 服务器收到对 URL
/foo/bar
的请求时,您可以将该 URL 重写为其他内容,然后 Web 服务器会在磁盘上查找匹配的文件它。简单的例子:此规则表示只要请求匹配“/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']
中的原始请求,因此它可以做任何它想做的事情有了它。首先,您将这些重写规则放入您的网络服务器配置文件中。 Apache 还允许*您将它们放入文档根目录中名为
.htaccess
的文件中(即 .php 文件旁边)。* 如果主 Apache 配置文件允许;它是可选的,但通常会启用。
mod_rewrite 不做什么
mod_rewrite 不会神奇地使所有 URL 变得“漂亮”。这是一个常见的误解。如果您的网站中有此链接:
mod_rewrite 无法使之变得漂亮。为了使其成为一个漂亮的链接,您必须:
将链接更改为漂亮的链接:
使用上述任何一种方法,在服务器上使用 mod_rewrite 来处理对 URL
/my/pretty/link
的请求。(可以使用
mod_substitute
结合转换传出的 HTML 页面及其包含的链接。尽管这通常比仅仅更新 HTML 资源更费力。)mod_rewrite 可以做很多事情,您可以创建非常复杂的匹配规则,包括链接多个重写、将请求代理到完全不同的服务或机器、返回特定的 HTTP 状态代码作为响应、重定向请求等。它非常强大,可以如果您了解基本的 HTTP 请求响应机制,将会非常有用。它不会自动使您的链接变得漂亮。
请参阅官方文档了解所有可能的标志和选项。