介绍
Apache的mod_rewrite
模块允许您以更清洁的方式重写URL,将可人读的路径翻译成代码友好的查询字符串,还允许您根据条件重写URL。
一个.htaccess 文件允许您创建和应用重写规则,而无需访问服务器配置文件. 通过将.htaccess 文件放置到您的网站的根部,您可以在每个网站或每个目录的基础上管理重写。
在本教程中,您将启用mod_rewrite
,并使用.htaccess
文件创建一个基本的URL重定向,然后探索一些先进的使用案例。
前提条件
要遵循本教程,您将需要:
- 一个 Debian 10 服务器通过遵循 Debian 10 初始服务器安装指南设置,包括一个 sudo 非 root 用户和防火墙。
步骤 1 – 启用mod_rewrite
为了使Apache能够理解重写规则,我们首先需要激活mod_rewrite
。它已经安装,但在默认的Apache安装中被禁用。
1sudo a2enmod rewrite
这会激活模块,或者提醒您模块已经启用,然后重新启动Apache:
1sudo systemctl restart apache2
mod_rewrite
现在已完全启用,下一步我们将设置一个.htaccess
文件,我们将使用它来定义重写重定向的规则。
第2步:设置.htaccess
一个.htaccess 文件允许我们修改我们的重写规则,而不需要访问服务器配置文件. 出于这个原因,.htaccess 对您的 Web 应用程序的安全至关重要。
<$>[注] **注:**您可以在.htaccess 文件中插入的任何规则也可以直接插入到服务器配置文件中。
然而,在这个简单的例子中,性能的增加将是微不足道的。此外,在.htaccess
中设置规则是方便的,尤其是在同一服务器上的多个网站上。 它不需要服务器重新启动,以便更改生效或 root 特权来编辑规则,简化维护和使用非特权帐户进行更改的过程。 流行的开源软件如Wordpress和Joomla依赖.htaccess
文件来根据需求进行更改和其他规则。
在您开始使用.htaccess 文件之前,您需要设置和保护一些其他设置。
默认情况下,Apache 禁止使用.htaccess 文件来应用重写规则,所以您首先需要允许对该文件进行更改。
1sudo nano /etc/apache2/sites-available/000-default.conf
在该文件中,你会发现一个从第一行开始的<VirtualHost *:80>
块。在该块中,添加下面的新块,以便您的配置文件看起来如下。
1[label /etc/apache2/sites-available/000-default.conf]
2<VirtualHost *:80>
3 <Directory /var/www/html>
4 Options Indexes FollowSymLinks
5 AllowOverride All
6 Require all granted
7 </Directory>
8
9 . . .
10</VirtualHost>
如果您使用了nano
,请按CTRL+X
,Y
,然后按ENTER
。
然后检查您的配置:
1sudo apache2ctl configtest
如果没有错误,请重新启动 Apache 以执行更改:
1sudo systemctl restart apache2
现在,在 Web 根中创建一个 .htaccess
文件:
1sudo nano /var/www/html/.htaccess
将此行添加到新文件的顶部以激活重写引擎。
1[label /var/www/html/.htaccess]
2RewriteEngine on
保存文件和退出。
现在你有一个操作的.htaccess 文件,你可以使用它来管理你的 Web 应用程序的路由规则. 在下一步,我们将创建一个样本网站文件,我们将使用它来演示重写规则。
步骤 3 – 配置 URL 重写
在这里,我们将设置一个基本的URL重写,将漂亮的URL转换为实际的页面路径,具体来说,我们将允许用户访问http://your_server_ip/about
,并显示一个名为about.html
的页面。
首先,在 Web 根中创建一个名为about.html
的文件:
1sudo nano /var/www/html/about.html
将以下HTML代码复制到文件中,然后保存并关闭它。
1[label /var/www/html/about.html]
2<html>
3 <head>
4 <title>About Us</title>
5 </head>
6 <body>
7 <h1>About Us</h1>
8 </body>
9</html>
您可以访问此页面在http://your_server_ip/about.html
,但请注意,如果您尝试访问http://your_server_ip/about
,您将看到一个 404 Not Found错误。 要访问该页面使用/about
,我们将创建一个重写规则。
所有RewriteRules
都遵循此格式:
1[label General RewriteRule structure]
2RewriteRule pattern substitution [flags]
RewriteRule
指明了指令.pattern
是符合浏览器中的浏览器类型所需的 URL 字符串的 常规表达式。substitution
是通往实际 URL 的路径,即 Apache 文件的路径。flag
是可修改规则运作方式的可选参数。
让我们创建我们的 URL 重写规则. 打开.htaccess 文件:
1sudo nano /var/www/html/.htaccess
在第一个行后,添加以下RewriteRule
,然后保存文件:
1[label /var/www/html/.htaccess]
2RewriteEngine on
3RewriteRule ^about$ about.html [NC]
在这种情况下,‘^about$’是模式,‘about.html’是替代,而‘[NC]’是旗帜。
^
表示 URL 开始,然后是your_server_ip/
.$
表示 URL 结束.about
匹配字符串about
.about.html
是用户访问的实际文件。
您现在可以在浏览器中访问 http://your_server_ip/about
. 事实上,在上面的规则中,下面的 URL 也将指向 about.html
:
http://your_server_ip/about
,因为规则的定义。http://your_server_ip/About
,因为规则是案例不敏感的。http://your_server_ip/about.html
,因为原始文件名将永远工作。
但是,以下方法不会起作用:
http://your_server_ip/about/
,因为规则明确指出在‘about’之后可能没有任何东西,因为‘$’字符出现在‘about’之后。
现在你有一个操作的.htaccess 文件,有一个基本的规则,你可以修改并扩展到你的需求. 在下面的部分,我们将显示两个额外的常用的指令示例。
示例 1 – 使用 RewriteRule 简化查询字符串
网页应用程序经常使用 query strings,它们在地址后使用一个问号(?
)附加到 URL. 单独的参数通过一个ampersand(&
)划界。
例如,一个以PHP编写的搜索结果页面可能使用一个URL,如http://example.com/results.php?item=shirt&season=summer
。在这个例子中,有两个额外的参数被传递到想象中的result.php
应用程序脚本中:项目
,具有衬衫
值,和季节
具有夏季
值。
Apache 重写规则通常被用来简化如上面的例子那样长而不愉快的链接到易于输入和视觉解读的 _friendly URLs。在这个例子中,我们希望简化上述链接成为http://example.com/shirt/summer
。
这里有一个规则来执行这一点:
1[label Simple substition]
2RewriteRule ^shirt/summer$ results.php?item=shirt&season=summer [QSA]
衬衫/夏季
在所请求的地址中被明确匹配,而Apache则被要求为results.php?item=shirt&season=summer
服务。
他们告诉Apache将任何额外的查询字符串附加到所服务的URL,所以如果访问者键入http://example.com/shirt/summer?page=2
,服务器将响应results.php?item=shirt&season=summer&page=2
。
虽然这种方法实现了所需的效果,但项目名称和季节都被硬编码为规则,这意味着规则不会适用于任何其他项目,如裤子
或季节,如冬季
。
为了使规则更为通用,我们可以使用 常规表达式来匹配原始地址的部分,并在替换模式中使用这些部分。
1[label Simple substition]
2RewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2 [QSA]
组合中的第一个正规表达式组合包含含有衬衫
或裤子
等字符和数字的字符串,并将匹配的片段保存为1美元
变量。
然后在项目
和季节
变量中使用相匹配的片段,而不是我们之前使用的硬编码的衬衫
和夏季
值。
例如,上面的例子会将 http://example.com/pants/summer
转换为 http://example.com/results.php?item=pants&season=summer
. 这个例子也是未来的证明,允许使用一个规则正确地重写多个项目和季节。
示例 2 — 使用 RewriteConds 使用逻辑添加条件
重写规则不一定总是一个接一个进行评估,没有任何限制。《重写规则》指令允许我们将条件添加到我们的重写规则中,以控制规则将何时被处理。
1[label General RewriteCond structure]
2RewriteCond TestString Condition [Flags]
RewriteCond
指定了RewriteCond
指令.TestString
是要测试的字符串.条件
是要匹配的模式或条件.旗帜
是可选的参数,可以修改条件和评估规则。
如果一个RewriteCond
被评估为真,则将考虑下一个RewriteRule
。如果没有,则将排除该规则。
例如,假设您希望将所有请求重定向到网站上不存在的文件或目录,返回主页,而不是显示标准 404 Not Found错误页面。
1[label Redirect all requests to non-existent files and directories to home page]
2RewriteCond %{REQUEST_FILENAME} !-f
3RewriteCond %{REQUEST_FILENAME} !-d
4RewriteRule . /
与上面的:
%{REQUEST_FILENAME}
是要检查的字符串. 在这种情况下,它是请求的文件名,这是每个请求可用的系统变量。-f
是一个内置条件,它验证了请求的名称是否存在于磁盘上,并且是一个文件。
最后一行中的RewriteRule
只适用于向不存在的文件或目录的请求,而RewriteRule
本身非常简单,并将每个请求重定向到/
网站根。
结论
「mod_rewrite」允许你创建可人读的URL. 在本教程中,你学会了如何使用「RewriteRule」指令来重定向URL,包括那些具有查询字符串的URL。
如果您想了解更多关于mod_rewrite的信息,请参阅Apache mod_rewrite的介绍(http://httpd.apache.org/docs/current/rewrite/intro.html)和Apache mod_rewrite的官方文档(http://httpd.apache.org/docs/current/mod/mod_rewrite.html)。