在CentOS 7上设置Apache的mod_rewrite的方法

发布于:2024-12-07 ⋅ 阅读:(32) ⋅ 点赞:(0)

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

简介

Apache 是一个模块化的 Web 服务器,允许您通过启用和禁用模块来定制其功能。这为管理员提供了定制 Apache 功能以满足其 Web 应用程序需求的能力。

在本教程中,我们将在 CentOS 7 服务器上安装 Apache,确认 mod_rewrite 模块已启用,并探索一些基本功能。

先决条件

在按照本教程操作之前,请确保您拥有一个具有 sudo 权限的常规非 root 用户。您可以从我们的指南《如何在 CentOS 上创建一个 Sudo 用户》中了解如何设置具有这些权限的用户。

步骤 1 – 安装 Apache

我们将使用 CentOS 的默认软件包管理实用程序 yum 来安装 Apache。

sudo yum install httpd

在出现 Is this ok [y/d/N]: 提示时,输入 Y 并按 ENTER 键授权安装。

接下来,使用 systemctl 实用程序启动 Apache 守护进程,它是一个独立的进程,创建一个子进程或线程池来处理请求:

sudo systemctl start httpd

要确保 Apache 成功启动,请使用 status 命令检查其状态:

sudo systemctl status httpd
. . .
systemd[1]: Starting The Apache HTTP Server...
systemd[1]: Started The Apache HTTP Server.

Apache 已经启动运行,现在让我们转向它的模块。

步骤 2 – 验证 mod_rewrite

在 CentOS 7 版本中,默认情况下启用了 mod_rewrite Apache 模块。我们将使用 httpd 命令和 -M 标志来验证这一点,该标志打印出所有已加载模块的列表:

httpd -M
. . .
remoteip_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
slotmem_plain_module (shared)
. . .

如果输出中没有出现 rewrite_module,则通过使用 vi 编辑器编辑 00-base.conf 文件来启用它:

sudo vi /etc/httpd/conf.modules.d/00-base.conf

一旦文本文件打开,输入 i 进入插入模式,然后添加或取消下面突出显示的行:

#
# This file loads most of the modules included with the Apache HTTP
# Server itself.
#
. . .
LoadModule rewrite_module modules/mod_rewrite.so
. . .

现在按 ESC 退出插入模式。然后,输入 :x 然后按 ENTER 键保存并退出文件。

接下来,通过重新启动 Apache 应用配置更改:

sudo systemctl restart httpd

安装了 Apache 并启用了 mod_rewrite 模块后,我们可以配置使用 .htaccess 文件。

步骤 3 – 设置 .htaccess 文件

.htaccess 文件允许在不更改服务器配置文件的情况下,在每个域的基础上定义 Apache 指令,包括 RewriteRule。在 Linux 中,以点(.)开头的文件被视为隐藏文件。

在使用 .htaccess 文件之前,我们需要更新 AllowOverride 设置以允许覆盖 Apache 指令。

sudo vi /etc/httpd/conf/httpd.conf

找到 <Directory /var/www/html> 部分,并将 AllowOverride 指令从 None 更改为 All

. . .
<Directory /var/www/html>
. . .
 # 
 # AllowOverride controls what directives may be placed in .htaccess files.
 # It can be "All", "None", or any combination of the keywords:
 # Options FileInfo AuthConfig Limit
 #
 AllowOverride All
. . .
</Directory>
. . .

保存并退出文件,然后重新启动 Apache 以应用更改:

sudo systemctl restart httpd

接下来,在 Apache 的默认文档根目录 /var/www/html 中创建一个 .htaccess 文件。

sudo vi /var/www/html/.htaccess

在文件顶部添加以下行以激活 RewriteEngine,指示 Apache 处理后续的任何规则:

RewriteEngine On

保存并退出文件。

现在您有了一个 .htaccess 文件,可以在其中定义规则以根据需要操作 URL。在我们开始编写实际规则之前,让我们花一点时间来回顾基本的 mod_rewrite 语法。

步骤 4 – 探索 RewriteRule 语法

RewriteRule 指令允许我们基于 URL 重新映射请求到 Apache。一个 .htaccess 文件可以包含多个重写规则,但在运行时,Apache 会按照它们定义的顺序应用规则。重写规则由以下结构组成:

RewriteRule Pattern Substitution [Flags]

  • RewriteRule:指定 RewriteRule 指令
  • Pattern:匹配所需字符串的 PCRE(Perl 兼容正则表达式)。您可以在这里了解更多关于正则表达式的信息。
  • Substitution:匹配请求应该发送到的位置
  • [Flags]:修改规则的可选参数。有关可用标志及其含义的更多信息,请参阅 Apache 的 Rewrite Flags 文档。

RewriteRulemod_rewrite 指令的主要工具,这就是为什么我们在本教程中主要关注它。

步骤 5 – 探索 RewriteCond 语法

RewriteCond 指令允许我们向重写规则添加条件。重写条件由以下结构组成:

RewriteCond TestString Condition [Flags]

  • RewriteCond:指定 RewriteCond 指令
  • TestString:要测试的字符串
  • Condition:要匹配的模式
  • [Flags]:可选参数,用于修改条件。

RewriteCond 指令不允许 Apache 考虑其后的任何重写规则,除非特定条件计算为真。

步骤 6 – 设置文件

我们将设置一个基本的重写规则,允许用户在 Web 浏览器的地址栏中访问 about.html 页面而无需输入文件扩展名(.html)。首先,在文档根目录中创建一个 about.html 文件:

sudo vi /var/www/html/about.html

将以下 HTML 代码复制到文件中:

<!DOCTYPE html>
<html>
    <head>
        <title>About Us</title>
    </head>
    <body>
        <h1>About Us</h1>
    </body>
</html>

保存并退出文件。

在 Web 浏览器中,导航至以下地址:

http://server_domain_or_IP/about.html

您应该会看到一个白色页面上面写着 About Us。如果您从地址栏中移除 .html 并重新加载页面,您将收到一个 404 Not Found 错误。Apache 只能通过完整文件名访问组件,但我们可以通过重写规则来改变这一点。

步骤 7 – 设置 RewriteRule

我们希望访问 About Us 页面的访问者无需输入 .html。为实现这一点,我们将创建一个规则。

打开 .htaccess 文件:

sudo vi /var/www/html/.htaccess

RewriteEngine On 行之后,添加以下内容:

RewriteRule ^about$ about.html [NC]

保存并退出文件。

访问者现在可以使用 http://server_domain_or_IP/about URL 访问 About Us 页面。

让我们来检查一下重写规则:

^about$ 用作从 URL 中匹配的模式,以及用户在其浏览器中输入的内容。

我们的示例使用了一些 元字符 来确保该术语仅存在于 URL 的特定位置:

  • ^ 表示 URL 的开始,在 server_domain_or_IP/ 之后被剥离。
  • $ 表示 URL 的结束。

about.html 显示了 Apache 在遇到匹配模式时提供的文件路径。

[NC] 是一个标志,指示重写规则不区分大小写,以便用户可以在 URL 中输入大小写字母。例如,以下 URL 指向 about.html 文件:

  • server_domain_or_IP/about
  • server_domain_or_IP/About
  • server_domain_or_IP/ABOUT

通过一个简单的重写规则,我们为用户访问 About Us 页面增加了动态方面。

常见模式

现在我们对重写规则有了基本的了解,我们将在本节中探索另外两个示例。

示例文件可以设置,但本教程不包括创建它们;仅包括重写规则本身。

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

Web 应用程序通常使用查询字符串,该查询字符串使用问号字符(?)附加到 URL,并由和号字符(&)分隔。Apache 在匹配重写规则时会忽略这两个字符。然而,有时可能需要查询字符串以在页面之间传递数据。例如,使用 PHP 编写的搜索结果页面的 URL 可能如下所示:

http://example.com/results.php?item=shoes&type=women

相反,我们希望访问者能够使用以下更简洁的 URL:

http://example.com/shoes/women

我们可以通过简单的替换或匹配选项之一来实现这些结果。

示例 1A:简单替换

我们将创建一个重写规则,执行简单的替换,简化长查询 URL:

RewriteRule ^shoes/women$ results.php?item=shoes&type=women

该规则将 shoes/women 映射到 results.php?item=shoes&type=women

示例 1B:匹配选项

在某些情况下,我们可能希望将查询字符串泛化以包括不同类型的鞋子。我们可以通过执行以下操作来实现:

  • 使用竖线 |,布尔“或”运算符,指定一系列选项
  • 使用 () 分组匹配,然后使用 $1 变量引用该组,1 代表第一个匹配的组

重写规则现在变为:

RewriteRule ^shoes/(men|women|youth) results.php?item=shoes&type=$1

上述规则匹配了以 shoes/ 开头的 URL,后跟指定类型。这将修改原始 URL,以便:

http://example.com/shoes/men

变为:

http://example.com/results.php?item=shoes&type=men

这种匹配选项允许 Apache 在无需为每个选项创建单独的重写规则的情况下评估多个模式。

示例 1C:匹配字符集

然而,我们还希望指定任何项目,而不仅限于 /shoes。因此,我们将执行以下操作:

  • 编写一个匹配所有字母数字字符的 正则表达式。方括号表达式 [ ] 匹配其中的任何字符,+ 匹配方括号中指定的任意数量的字符
  • 分组匹配,并使用文件中的第二个变量 $2 引用它
RewriteRule ^([A-Za-z0-9]+)/(men|women|youth) results.php?item=$1&type=$2

上述示例将把:

http://example.com/pants/men

转换为:

http://example.com/results.php?item=pants&type=men

我们成功地扩展了匹配能力,以包括 URL 的多个方面。

示例 1D:传递查询字符串

本节不介绍任何新概念,而是解决可能出现的问题。使用上述示例,假设我们希望重定向 http://example.com/pants/men,但会传递额外的查询字符串 ?page=2。我们希望将以下 URL 映射为:

http://example.com/pants/men?page=2

到:

http://example.com/results.php?item=pants&type=men&page=2

如果您尝试使用当前设置访问上述 URL,您会发现查询字符串 page=2 丢失了。这很容易通过使用额外的 QSA 标志来解决,该标志会导致查询字符串被合并。修改重写规则以匹配以下内容将实现所需的行为。

RewriteRule ^([A-Za-z0-9]+)/(men|women|youth) results.php?item=$1&type=$2 [QSA]

示例 2: 使用逻辑添加条件

现在我们来看一下 RewriteCond 指令的使用。如果重写条件评估为真,那么 Apache 将考虑其后的 RewriteRule

示例 2A: 默认页面

之前,我们看到 Apache 处理对无效 URL 的请求时会提供一个 404 未找到 页面。然而,我们希望所有格式错误的 URL 被重定向回首页,而不是显示错误页面。通过使用条件,我们可以检查请求的文件是否存在。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/(.*)$ /admin/home

这将把类似 /admin/random_text 的请求重定向到 /admin/home

让我们解析上述规则:

  • %{REQUEST_FILENAME} 检查请求的字符串
  • !-f !not 运算符表示如果请求的文件名不存在,则执行以下重写规则。
  • RewriteRule 将请求重定向回 /admin/home

遵循最佳实践,定义 404 ErrorDocument。为此,我们将创建一个 ErrorDocument 规则,将 404 错误指向一个 error.html 页面:

ErrorDocument 404 /error.html

这将把任何导致 HTTP 404 响应的请求重定向到 error.html 页面。

示例 2B: IP 地址限制

RewriteCond 可以用于允许特定 IP 地址访问站点。

此示例阻止除 198.51.100.24 之外的所有地方的流量。

RewriteCond %{REMOTE_ADDR} !^(198\.51\.100\.24)$
RewriteRule (.*) - [F,L]

整个规则表示,如果请求资源的 IP 地址不是 198.51.100.24,则不允许访问。

简而言之:

  • %{REMOTE_ADDR} 是地址字符串
  • !^(198\.51\.100\.24)$ 否定 IP 地址。\ 反斜杠用于转义 . 点,否则它们将作为元字符用于匹配任何字符。
  • F 标志禁止访问,L 标志表示这是最后一个要运行的规则,如果执行。

如果您更愿意阻止来自特定地址的访问,请改用以下内容:

RewriteCond %{REMOTE_ADDR} ^(198\.51\.100\.24)$
RewriteRule (.*) - [F,L]

尽管您可以使用其他方法来阻止或允许流量访问您的站点,但在 .htaccess 文件中设置限制是实现这些结果的最简单方法。

结论

在本教程中,我们使用了 .htaccess 文件来处理 RewriteRuleRewriteCond 指令。有许多理由使用重写规则,以下资源详细介绍了 mod_rewrite 模块的功能:

  • Apache mod_rewrite 介绍
  • mod_rewrite 文档
  • mod_rewrite 速查表

mod_rewrite 模块是 Apache web 服务器的关键组件,您可以用它做很多事情。然而,事情并不总是按计划进行,当发生这种情况时,您可能会发现自己陷入重定向循环或出现模糊的 500 forbidden 错误。有关调试这些情况的提示,请参阅这篇 StackOverflow 帖子。