前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
简介
在本教程中,我们将激活并学习如何使用 Apache 2 的 mod_rewrite
模块来管理 URL 重写。该模块允许我们以更清晰的方式重写 URL,将人类可读的路径转换为对代码友好的查询字符串,或者基于额外条件重定向 URL。
本指南分为两部分。第一部分设置一个示例网站,并涵盖一个简单的重写示例。第二部分包含两个更深入的常用重写规则示例。
先决条件
要遵循本教程,您需要:
- 一个安装了 Ubuntu 16.04 服务器,按照初始服务器设置教程进行设置,包括一个具有 sudo 非根用户和防火墙的服务器。
- 通过按照在 Ubuntu 16.04 上安装 Linux、Apache、MySQL、PHP(LAMP)堆栈的第 1 步来在服务器上安装 Apache 2。
第 1 步 —— 启用 mod_rewrite
首先,我们需要激活 mod_rewrite
。在干净的 Apache 2 安装中,该模块是可用但未启用的。
sudo a2enmod rewrite
这将激活该模块,或者提醒您该模块已经启用。要使这些更改生效,请重新启动 Apache。
sudo systemctl restart apache2
mod_rewrite
现在已完全启用。在下一步中,我们将设置一个 .htaccess
文件,我们将使用它来定义重定向的重写规则。
第 2 步 —— 设置 .htaccess
.htaccess
文件允许我们修改我们的重写规则,而无需访问服务器配置文件。因此,.htaccess
对于您的 Web 应用程序的安全性至关重要。在文件名之前的句点确保该文件是隐藏的。
我们需要在开始之前设置和保护一些其他设置。
默认情况下,Apache 禁止使用 .htaccess
文件应用重写规则,因此首先需要允许对该文件进行更改。使用 nano
或您喜欢的文本编辑器打开默认的 Apache 配置文件。
sudo nano /etc/apache2/sites-available/000-default.conf
在该文件中,您将在第一行找到一个以 <VirtualHost *:80>
开头的块。在该块内,添加以下新块,使您的配置文件看起来像下面这样。确保所有块都正确缩进。
<VirtualHost *:80>
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
. . .
</VirtualHost>
保存并关闭文件。要使这些更改生效,请重新启动 Apache。
sudo systemctl restart apache2
现在,在 Web 根目录中创建 .htaccess
文件。
sudo nano /var/www/html/.htaccess
在新文件的顶部添加此行以激活重写引擎。
RewriteEngine on
保存文件并退出。
现在,您有一个可操作的 .htaccess
文件,您可以使用它来管理您的 Web 应用程序的路由规则。在下一步中,我们将创建示例网站文件,以演示重写规则。
第 3 步 —— 配置 URL 重写
在这里,我们将设置一个基本的 URL 重写,将漂亮的 URL 转换为实际的代码路径。具体来说,我们将允许用户访问 http://your_server_ip/about
。
首先,在 Web 根目录中创建一个名为 about.html
的文件。
sudo nano /var/www/html/about.html
将以下 HTML 代码复制到文件中,然后保存并关闭它。
<html>
<head>
<title>About Us</title>
</head>
<body>
<h1>About Us</h1>
</body>
</html>
您可以通过 http://your_server_ip/about.html
访问此页面,但请注意,如果尝试访问 http://your_server_ip/about
,您将看到 404 Not Found 错误。如果您希望用户仅使用 about
访问页面,则重写规则将允许此功能。
所有 RewriteRules
遵循以下格式:
RewriteRule pattern substitution [flags]
RewriteRule
指定指令。pattern
是一个正则表达式,用于匹配 URL 中的所需字符串,即浏览器中用户键入的内容。substitution
是实际 URL 的路径,即 Apache 服务器的文件路径。flags
是可选参数,可以修改规则的工作方式。
打开 .htaccess
文件。
sudo nano /var/www/html/.htaccess
在第一行之后,添加标记为红色的 RewriteRule
并保存文件。
RewriteEngine on
RewriteRule ^about$ about.html [NC]
在这种情况下,^about$
是模式,about.html
是替换,[NC]
是一个标志。我们的示例使用了一些具有特殊含义的字符:
^
表示 URL 的开始,在your_server_ip/
之后。$
表示 URL 的结束。about
匹配字符串 “about”。about.html
是用户访问的实际文件。[NC]
是一个标志,使规则不区分大小写。
现在,您应该能够在浏览器中访问 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
之后可能没有任何内容,使用$
字符。http://your_server_ip/contact
,因为它不会匹配规则中的about
字符串。
现在,您有一个具有简单规则的可操作的 .htaccess
文件,您可以根据需要修改和扩展它。在接下来的几节中,我们将展示两个常用指令的其他示例。
示例 1 — 使用 RewriteRule 简化查询字符串
Web 应用程序通常使用 查询字符串,它们是通过在地址后面使用问号 (?
) 添加的。不同的参数使用和号 (&
) 分隔。查询字符串可用于在单个应用程序页面之间传递附加数据。
例如,一个用 PHP 编写的搜索结果页面可能使用类似 http://example.com/results.php?item=shirt&season=summer
的 URL。在这个例子中,两个额外的参数被传递给虚构的 result.php
应用程序脚本:item
,值为 shirt
,和 season
,值为 summer
。应用程序可以使用查询字符串信息来为访问者构建正确的页面。
Apache 重写规则通常用于简化上述长且不友好的链接,将其转换为更容易输入和视觉解释的 友好 URL。在这个例子中,我们希望简化上述链接,变成 http://example.com/shirt/summer
。shirt
和 summer
参数值仍然在地址中,但没有查询字符串和脚本名称。
以下是实现此目的的一条规则:
RewriteRule ^shirt/summer$ results.php?item=shirt&season=summer [QSA]
shirt/summer
在请求的地址中被显式匹配,并告诉 Apache 服务于 results.php?item=shirt&season=summer
。
[QSA]
标志通常用于重写规则。它们告诉 Apache 将任何额外的查询字符串附加到提供的 URL,因此如果访问者输入 http://example.com/shirt/summer?page=2
,服务器将响应 results.php?item=shirt&season=summer&page=2
。如果没有这个标志,额外的查询字符串将被丢弃。
虽然这种方法实现了期望的效果,但项目名称和季节都是硬编码到规则中的。这意味着该规则对于其他项目(如 pants
)或季节(如 winter
)将无法工作。
为了使规则更通用,我们可以使用正则表达式匹配原始地址的部分,并在替换模式中使用这些部分。修改后的规则如下:
RewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2 [QSA]
括号中的第一个正则表达式组匹配包含字母数字字符的字符串,如 shirt
或 pants
,并将匹配的片段保存为 $1
变量。括号中的第二个正则表达式组匹配 summer
、winter
、fall
或 spring
,类似地将匹配的片段保存为 $2
。
然后,在生成的 URL 中使用匹配的片段,而不是之前使用的硬编码的 shirt
和 summer
值。
上述规则将例如 http://example.com/pants/summer
转换为 http://example.com/results.php?item=pants&season=summer
。这个例子也是未来可扩展的,允许使用单个规则正确重写多个项目和季节。
示例 2 — 使用 RewriteConds 添加逻辑条件
重写规则不一定总是无限制地逐个评估。RewriteCond
指令允许我们向重写规则添加条件,以控制何时处理规则。所有 RewriteConds
遵循以下格式:
RewriteCond TestString Condition [Flags]
RewriteCond
指定RewriteCond
指令。TestString
是要测试的字符串。Condition
是要匹配的模式或条件。Flags
是可选参数,可能修改条件和评估规则。
如果 RewriteCond
评估为真,则紧随其后的 RewriteRule
将被考虑。如果不是,则规则将被丢弃。可以连续使用多个 RewriteCond
,并且默认行为下,所有条件必须都为真才能考虑后续规则。
例如,假设您希望将站点上所有对不存在的文件或目录的请求重定向回主页,而不是显示标准的 404 Not Found 错误页面。可以通过以下条件规则实现:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /
使用上述规则:
%{REQUEST_FILENAME}
是要检查的字符串。在这种情况下,它是请求的文件名,这是每个请求都可用的系统变量。-f
是一个内置条件,用于验证请求的名称是否存在于磁盘上并且是一个文件。!
是一个否定运算符。组合起来,!-f
仅在指定的名称不存在或不是文件时评估为真。- 类似地,
!-d
仅在指定的名称不存在或不是目录时评估为真。
最后一行上的 RewriteRule
仅对不存在的文件或目录的请求生效。RewriteRule
本身非常简单,将每个请求重定向到 /
网站根目录。
结论
mod_rewrite
是一个有用的 Apache 模块,可以有效地用于确保人类可读的 URL。在本教程中,您学习了如何使用 RewriteRule
指令重定向 URL,包括带有查询字符串的 URL。您还学习了如何使用 RewriteCond
指令有条件地重定向 URL。
如果您想了解更多关于 mod_rewrite
的信息,请查看 Apache 的 mod_rewrite 介绍和 Apache 的官方 mod_rewrite 文档。