作者选择了 多样性在技术基金作为 写给捐款计划的一部分接受捐款。
介绍
Apache的mod_rewrite
模块允许您更清晰地重写URL,将可人读的路径翻译成代码友好的查询字符串,还允许您根据条件重写URL。
一个.htaccess 文件允许您创建和应用重写规则,而无需访问服务器配置文件. 通过将.htaccess 文件放置到您的网站的根部,您可以在每个网站或每个目录的基础上管理重写。
在本教程中,您将启用mod_rewrite
,并使用.htaccess
文件创建一个基本的URL重定向,然后探索一些先进的使用案例。
前提条件
要遵循本教程,您将需要:
- 一个Ubuntu 22.04 服务器通过遵循 Ubuntu 22.04 初始服务器设置指南设置,包括一个 sudo 非根用户和防火墙。
步骤 1 – 启用mod_rewrite
为了让 Apache 能够理解重写规则,你首先需要激活mod_rewrite
。它已经安装了,但在默认的 Apache 安装中被禁用。
1sudo a2enmod rewrite
这将激活模块或提醒您,模块已经启用了。
1sudo systemctl restart apache2
「mod_rewrite」现在已完全启用,下一步,您将设置一个「.htaccess」文件,您将使用它来定义重写重定向的规则。
第2步:设置.htaccess
一个.htaccess
文件允许我们修改你的重写规则而无需访问服务器配置文件. 因此,.htaccess
对您的Web应用程序的安全至关重要。
<$>[注] **注:**您可以在.htaccess 文件中插入的任何规则也可以直接插入到服务器配置文件中。
然而,在这个简单的例子中,性能的增加将是微不足道的。此外,在.htaccess
中设置规则是方便的,尤其是在同一服务器上的多个网站上。 它不需要服务器重新启动,以便更改生效,并且不需要根特权来编辑这些规则,简化维护,并通过非特权帐户实现更改。 一些流行的开源软件,如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>
保存并关闭文件. 若要执行这些更改,请重新启动 Apache。
1sudo systemctl restart apache2
现在,在 webroot 中创建一个 .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
的页面。
首先,在 webroot 中创建一个名为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 substitution]
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 substitution]
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 . / [R=301]
与上面的:
%{REQUEST_FILENAME}
是要检查的字符串. 在这种情况下,它是请求的文件名,这是每个请求可用的系统变量。-f
是一个内置条件,它验证了请求的名称是否存在于磁盘上,并且是一个文件。
最后一行中的RewriteRule
只适用于向不存在的文件或目录的请求,而RewriteRule
本身非常简单,模式中的点
匹配任何内容,而替换则会将每个请求指向网站的/
根。
此外,[R=301]
旗告诉Apache将一个 _301 Moved Permanently_重定向HTTP响应代码返回到浏览器中,结果是一个浏览器知道重定向发生了,并明确采集网站根,而不是所请求的URL,变化反映在浏览器地址栏上。
如果没有这个标志,Apache会返回网站的根内容,但浏览器仍然会认为所请求的页面URL存在,并会在地址栏上显示最初请求的地址。
结论
「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)。