如何在Ubuntu 16.04上用Apache的mod_rewrite重写URL

介绍

在本教程中,我们将激活并学习如何使用Apache 2的 mod_rewrite模块管理URL重写。此模块允许我们以更清晰的方式重写URL,将人类可读的路径转换为对代码友好的查询字符串或基于附加条件重定向URL。 本指南分为两部分。第一个设置示例网站并涵盖了一个简单的重写示例。第二部分包含两个常用的重写规则的更深入的例子。

先决条件

要遵循本教程,您需要:

第1步 - 启用mod_rewrite

首先,我们需要激活 mod_rewrite 。它可用,但没有启用干净的Apache 2安装。
sudo a2enmod rewrite
这将激活模块或警告您模块已启用。要使这些更改生效,请重新启动Apache。
sudo systemctl restart apache2
mod_rewrite现在完全启用。 在下一步中,我们将设置一个 .htaccess文件,我们将用它来定义重定向的重写规则。

第2步 - 设置.htaccess

.htaccess文件允许我们在不访问服务器配置文件的情况下修改我们的重写规则。 因此, .htaccess对于您的Web应用程序的安全性至关重要。文件名前面的时间段确保文件被隐藏。 注意:可以放在 .htaccess文件中的任何规则也可以直接放入服务器配置文件中。 事实上, 官方Apache文档建议使用服务器配置文件,而不是 .htaccess ,因为Apache以这种方式处理它。 然而,在这个简单的例子中,性能提高可以忽略不计。此外,在 .htaccess中设置规则很方便,尤其是在同一服务器上有多个网站的情况下。 它不需要服务器重新启动才能使更改生效,并且不需要root权限即可编辑这些规则,从而简化维护并使用非特权帐户进行更改。 一些流行的开源软件,如Wordpress和Joomla,通常依赖于 .htaccess文件,软件可以根据需要修改和创建其他规则。 在开始之前,我们需要设置并保护一些其他设置。 默认情况下,Apache禁止使用 .htaccess文件来应用重写规则,因此首先需要允许对文件进行更改。 使用 nano或您喜欢的文本编辑器打开默认的Apache配置文件。
sudo nano /etc/apache2/sites-available/000-default.conf
在该文件中,您会发现从第一行开始的 <VirtualHost *:80>块。在该块内部,添加以下新块,以便您的配置文件如下所示。确保所有块都正确缩进。
/etc/apache2/sites-available/000-default.conf
<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
在新文件的顶部添加此行,以激活重写引擎。
/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代码复制到文件中,然后保存并关闭它。
/var/www/html/about.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错误。如果你希望用户简单地访问页面,重写规则将允许这个功能。 所有 RewriteRules遵守以下格式:
一般RewriteRule结构
RewriteRule pattern substitution [flags]
  • RewriteRule指定指令。
  • pattern是与URL中所需的字符串匹配的正则表达式 ,这是浏览器在浏览器中键入的内容。
  • substitution是实际URL的路径,即文件Apache服务器的路径。
  • flags是可以修改规则工作原理的可选参数。
打开 .htaccess文件。
sudo nano /var/www/html/.htaccess
在第一行之后,添加以红色标记的 RewriteRule并保存文件。
/var/www/html/.htaccess
RewriteEngine on
RewriteRule ^about$ about.html [NC]
在这种情况下, ^about$是模式, about.html是替换,并且 [NC]是标志。我们的示例使用了几个具有特殊意义的字符:
  • ^表示网址的开头,位于your_server_ip /之后。
  • $表示URL的结尾。
  • about匹配字符串“about”。
  • about.html是用户访问的实际文件。
  • [NC]是使规则不区分大小写的标志。
现在,您现在应该可以在浏览器中访问 http:// your_server_ip /about 。 实际上,根据上面显示的规则,以下网址将指向 about.html
  • http:// your_server_ip /about ,因为规则定义。
  • http:// your_server_ip /About ,因为规则不区分大小写。
  • http:// your_server_ip /about.html ,因为原始的正确文件名将始终有效。
以下不会:
  • http:// your_server_ip /about/ ,因为规则明确声明在使用$字符后可能没有任何内容。
  • http:// your_server_ip /contact ,因为它不会匹配规则中的about字符串。
您现在有一个操作 .htaccess文件,有一个简单的规则,您可以修改和扩展到您的需要。在以下部分中,我们将显示常用指令的两个附加示例。

示例1 - 使用RewriteRule简化查询字符串

Web应用程序通常使用 查询字符串 ,这些 字符串在地址后面使用问号( ? )附加到URL。 单独的参数使用 &符号( & )分隔。查询字符串可用于在各个应用程序页之间传递附加数据。 例如,以PHP编写的搜索结果页可能使用类似 http://example.com/results.php?item=shirt&season=summer的网址。 在这个例子中,两个附加参数被传递给假想的 result.php应用程序脚本: item ,值为 shirt ,而 season为值 summer 。应用程序可以使用查询字符串信息为访问者构建正确的页面。 通常使用Apache重写规则来简化这样的长和不连续的链接,如上面到更容易键入和视觉解释的 友好URL 。 在这个例子中,我们想简化上面的链接,成为 http://example.com/shirt/summershirtsummer参数值仍然在地址中,但没有查询字符串和脚本名称。 这里有一个规则来实现这一点:
简单替换
RewriteRule ^shirt/summer$ results.php?item=shirt&season=summer [QSA]
shirt/summer在请求的地址中明确匹配,并且Apache被告知要投放 results.php?item=shirt&season=summer[QSA]标志通常用于重写规则。 他们告诉Apache为所提供的网址附加任何其他查询字符串,因此如果访问者键入 http://example.com/shirt/summer? page=2 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]
括号中的第一个正则表达式组匹配包含字母数字字符和数字(如 shirtpants的字符串,并将匹配的片段保存为 $1变量。 括号中的第二个常规rexpression组完全匹配 summerwinterfallspring ,并且类似地将匹配的片段保存为 $2 。 匹配的片段然后在 itemseason变量的结果URL中使用,而不是我们以前使用的硬编码的 shirtsummer值。 以上操作会将例如 http://example.com/pants/summer转换为 http://example.com/results.php?item=pants&season=summer 。此示例也是未来证明,允许使用单个规则正确地重写多个项目和季节。

示例2 - 使用RewriteConds通过逻辑添加条件

重写规则不一定总是一个接一个地评估,没有任何限制。 RewriteCond指令允许我们为我们的重写规则添加条件,以控制何时处理规则。 所有 RewriteConds遵守以下格式:
一般RewriteCond结构
RewriteCond TestString Condition [Flags]
  • RewriteCond指定RewriteCond指令。
  • TestString是要测试的字符串。
  • Condition是匹配的模式或条件。
  • Flags是可以修改条件和评估规则的可选参数。
如果 RewriteCond计算结果为true,则将 RewriteRule紧随其后的RewriteRule。 如果不是,则规则将被丢弃。 多个 RewriteCond可以一个接一个使用,并且对于默认行为,对于要考虑的以下规则,所有必须求值为真。 例如,假设您想将所有请求重定向到主页上的不存在的文件或目录,而不是显示标准的 404未找到错误页面。这可以通过以下条件规则实现:
将所有不存在的文件和目录的请求重定向到主页
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /
用上面的:
  • %{REQUEST_FILENAME}是要检查的字符串。在这种情况下,它是请求的文件名,它是可用于每个请求的系统变量。
  • -f是一个内置条件,它验证所请求的名称是否存在于磁盘上,并且是一个文件。 ! 是一个否定运算符。 组合, !-f仅当指定的名称不存在或不是文件时才会计算为true。
  • 类似地,仅当指定的名称不存在或不是目录时, !-d才会求值为true。
最后一行的 RewriteRule将仅对不存在的文件或目录的请求生效。 RewriteRule本身非常简单,并将每个请求重定向到 /网站根目录。

结论

mod_rewrite是一个有用的Apache模块,可以有效地使用,以确保人类可读的URL。 在本教程中,您学习了如何使用 RewriteRule伪指令重定向URL,包括具有查询字符串的URL。 您还学习了如何使用 RewriteCond指令有条件地重定向URL。 如果你想了解更多关于 mod_rewrite ,请参考 Apache的mod_rewrite简介Apache的官方文档mod_rewrite
赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏