介绍
在本教程中,我们将激活并学习如何使用Apache 2的mod_rewrite
模块来管理URL重写,该模块允许我们以更清洁的方式重写URL,将人读路径翻译成代码友好的查询字符串或根据额外的条件重定向URL。
本指南分为两部分,第一部分设置了一个示例网站,并涵盖一个简单的重写示例,第二部分包含两个更深入的常用的重写规则示例。
前提条件
要遵循本教程,您将需要:
- 一个 Ubuntu 16.04 服务器安装了 此初始服务器设置教程,包括一个 sudo 非根用户和防火墙。
- Apache 2 安装在您的服务器上,按照 如何在 Ubuntu 16.04 上安装 Linux, Apache, MySQL, PHP (LAMP) 堆栈的步骤 1。
步骤 1 – 启用mod_rewrite
首先,我们需要激活mod_rewrite,但在清洁的Apache 2安装中无法启用。
1sudo a2enmod rewrite
这将激活模块或提醒您,模块已经启用了。
1sudo systemctl restart apache2
mod_rewrite
现在已完全启用,下一步我们将设置一个.htaccess
文件,我们将使用它来定义重写重定向的规则。
第2步:设置.htaccess
一个.htaccess 文件允许我们修改我们的重写规则,而不需要访问服务器配置文件. 出于这个原因,.htaccess 对您的 Web 应用程序的安全至关重要。
<$>[注] **注:**您可以在.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 MultiViews
5 AllowOverride All
6 Require all granted
7 </Directory>
8
9 . . .
10</VirtualHost>
保存并关闭文件. 若要执行这些更改,请重新启动 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`。
首先,在 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错误。
所有重写规则
都遵循以下格式:
1[label General RewriteRule structure]
2RewriteRule pattern substitution [flags]
RewriteRule
指明了指令。pattern
是符合浏览器中的浏览器类型所需的 URL 字符串的 常规表达式 。substitution
是通往实际 URL 的路径,即 Apache 文件服务器的路径。flag
是可修改规则运作方式的可选参数。
打开.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/
,因为规则明确指出,使用‘$’字符后可能没有任何东西。
现在你有一个操作的 .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」是一個有用的Apache模塊,可以有效地使用來確保人類可讀的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)。