如何在 CentOS 7 上为 Apache 设置 mod_rewrite

介绍

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

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

前提条件

在遵循本教程之前,请确保您有一个有 sudo 特权的常规非 root 用户,您可以从我们的指南中了解如何设置具有这些特权的用户, 如何在 CentOS 上创建 Sudo 用户

步骤 1 - 安装 Apache

我们将使用yum安装Apache,这是CentOS的默认包管理工具。

1sudo yum install httpd

当被提示使用Is this ok [y/d/N]:消息时,键入Y并按ENTER键授权安装。

接下来,使用systemctl实用程序启动Apache DAEMON,一个独立的过程,创建了一个小程序或线程集合来处理请求:

1sudo systemctl start httpd

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

1sudo systemctl status httpd
1[secondary_label Output]
2. . .
3systemd[1]: Starting The Apache HTTP Server...
4systemd[1]: Started The Apache HTTP Server.

随着Apache的启动和运行,让我们把注意力转向其模块。

步骤 2 – 验证 mod_rewrite

从CentOS 7版本开始,Apache模块mod_rewrite是默认启用的,我们将通过httpd命令和-M旗进行验证,该命令打印了所有加载的模块的列表:

1httpd -M
1[secondary_label Output]
2 . . .
3 remoteip_module (shared)
4 reqtimeout_module (shared)
5 rewrite_module (shared)
6 setenvif_module (shared)
7 slotmem_plain_module (shared)
8 . . .

如果「rewrite_module」不在输出中,请通过使用「vi」编辑器编辑「00-base.conf」文件来启用它:

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

一旦文本文件打开,键入i,进入插入模式,然后添加或删除下面的突出行:

1[label /etc/httpd/conf.modules.d/00-base.conf]
2#
3# This file loads most of the modules included with the Apache HTTP
4# Server itself.
5#
6. . .
7LoadModule rewrite_module modules/mod_rewrite.so
8. . .

现在按ESC,离开插入模式,然后键入:x,然后按ENTER键来保存和退出文件。

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

1sudo systemctl restart httpd

安装了Apache并启用了mod_rewrite模块,我们已经准备好配置一个.htaccess文件的使用。

步骤 3 – 设置一个.htaccess 文件

一个.htaccess 文件允许定义 Apache 的指令,包括一个 "RewriteRule",每个域的基础上,而不会改变服务器配置文件。

在使用.htaccess 文件之前,我们需要更新AllowOverride设置,以便能够重写 Apache 指令。

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

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

 1[label /etc/httpd/conf/httpd.conf]
 2. . .
 3<Directory /var/www/html>
 4. . .
 5 # 
 6 # AllowOverride controls what directives may be placed in .htaccess files.
 7 # It can be "All", "None", or any combination of the keywords:
 8 # Options FileInfo AuthConfig Limit
 9 #
10 AllowOverride All
11. . .
12</Directory>
13. . .

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

1sudo systemctl restart httpd

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

1sudo vi /var/www/html/.htaccess

将下列行添加到文件的顶部,以激活重写引擎,指示Apache处理以下任何规则:

1[label /var/www/html/.htaccess]
2RewriteEngine On

保存和退出文件。

你现在有一个.htaccess文件,它会让你定义规则来根据需要操纵URL。

步骤 4 – 探索 RewriteRule 语法

RewriteRule指令允许我们根据URL将请求重写到Apache,一个.htaccess文件可以容纳多个重写规则,但在运行时,Apache将规则应用于它们的定义顺序。

「重寫規則模式替代(旗)」

  • RewriteRule:指定RewriteRule指令
  • Pattern:匹配所需字符串的PCRE(Perl Compatible Regular Expression)。您可以了解更多关于常规表达式的信息(在这里)。
  • Substitution:应发送匹配请求的位置

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

步骤 5 – 探索 RewriteCond 语法

RewriteCond指令允许我们将条件添加到重写规则中,重写条件由以下结构组成:

「RewriteCond TestString 條件 [旗]」

  • RewriteCond:指定RewriteCond指令
  • TestString:对 进行测试的字符串 * Condition:与 匹配的模式 * Flags:可选参数来修改条件。

RewriteCond指令不允许Apache考虑遵循的任何重写规则,除非该特定条件被评估为真实。

步骤6 - 设置文件

我们将设置一个基本的重写规则,允许用户访问有关.html 的页面,而不需要在 Web 浏览器的地址栏中输入文件扩展(.html)。

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

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

 1[label /var/www/html/about.html]
 2<!DOCTYPE html>
 3<html>
 4    <head>
 5        <title>About Us</title>
 6    </head>
 7    <body>
 8        <h1>About Us</h1>
 9    </body>
10</html>

保存和退出文件。

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

1http://server_domain_or_IP/about.html

如果您从地址栏中删除 .html并重新加载该页面,您将收到一个 404 ** Not Found** 错误。

步骤7 - 设置一个重写规则

我们希望有关我们页面的访问者可以访问它,而无需键入.html

打开.htaccess 文件:

1sudo vi /var/www/html/.htaccess

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

1[label /var/www/html/.htaccess]
2RewriteRule ^about$ about.html [NC]

保存和退出文件。

现在,访问者可以访问关于我们的页面,使用http://server_domain_or_IP/about URL。

让我们来看看重写规则:

^about$ 作为从 URL 和用户在其浏览器中输入的内容进行匹配的模式。 我们的示例使用了一对 metacharacters 来确保该术语只存在于 URL 中的特定位置:

  • ^ 表示 URL 的开始,在 server_domain_or_IP/ 被删除后。
  • & 表示 URL 的结束。

about.html 显示了当 Apache 遇到匹配模式时服务的文件路径。

[NC] 是一个旗帜,指示重写规则不敏感,以便用户可以在 URL 中输入较低和较高字母。

  • server_domain_or_IP/about server_domain_or_IP/about server_domain_or_IP/about

通过简单的重写规则,我们为用户如何访问关于我们**页面添加了一个动态方面。

共同模式

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

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

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

网页应用程序经常使用查询字符串,这些字符串是使用问号字符号(?)附加到 URL,并由 ampersand字符(&)划界。Apache在匹配重写规则时忽略了这两个字符串。

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

相反,我们希望我们的访客能够使用以下清洁 URL:

1http://example.com/shoes/women

我们可以以两种方式实现这些结果 - 通过简单的更换或匹配选项。

示例1A:简单取代

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

1[label /var/www/html/.htaccess]
2RewriteRule ^shoes/women$ results.php?item=shoes&type=women

该规则将鞋子/女士转到结果.php?item=鞋子&类型=女士

示例1B:匹配选项

在某些情况下,我们可能希望将查询字符串概括为包括不同类型的鞋子。

  • 使用垂直管道的选项系列指定,布尔式OR运算符
  • 使用()组合匹配,然后使用$1变量引用组合,以1为第一个匹配的组合

重写规则现在变成:

1[label /var/www/html/.htaccess]
2RewriteRule ^shoes/(men|women|youth) results.php?item=shoes&type=$1

上面的规则匹配一个鞋子/的URL,然后是指定的类型,这将修改原始URL,以便:

1http://example.com/shoes/men

变成:

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

此匹配选项允许Apache评估多个模式,而无需为每个模式创建单独的重写规则。

示例1C:匹配字符集

但是,我们也想指定任何项目,而不是仅限于鞋子

  • 写一个 regular 表达式 匹配所有字符。 支架表达式 [ ] 匹配其内部的任何字符,而 `+ 匹配在支架
  • 组合匹配的任何字符的数量,并将其参考为 $2 作为文件中的第二个变量
1[label /var/www/html/.htaccess]
2RewriteRule ^([A-Za-z0-9]+)/(men|women|youth) results.php?item=$1&type=$2

上面的例子将转换为:

1http://example.com/pants/men

二:

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

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

例1D:通过查询字符串

使用上面的例子,假设我们想重定向 http://example.com/pants/men,但会通过一个额外的查询字符串 ?page=2

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

二:

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

如果您尝试使用当前设置访问上述 URL,您会发现查询字符串 page=2 丢失,这很容易通过使用额外的 QSA 标志来修复,从而导致查询字符串组合。

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

例子二:用逻辑添加条件

现在我们将研究使用RewriteCond指令,如果重写条件被评估为真,那么Apache会考虑随之而来的RewriteRule

** 示例 2A:默认页面**

以前,我们看到Apache通过提供404 Not Found页面来处理一个无效的URL请求,但是,而不是错误页面,我们希望所有错误的URL被重定向回首页。

1[label /var/www/html/.htacces]
2RewriteCond %{REQUEST_FILENAME} !-f
3RewriteRule ^admin/(.*)$ /admin/home

这将重定向某些东西,如/admin/random_text/admin/home

让我们分解上面的规则:

  • %{REQUEST_FILENAME} 检查所请求的字符串
  • !-f!not 操作员表示,如果所请求的文件名不存在,则执行以下重写规则。

要做到这一点,我们将创建一个ErrorDocument规则,将404错误指向一个error.html页面:

1[label /var/www/html/.htaccess]
2ErrorDocument 404 /error.html

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

例2B:IP地址限制

RewriteCond可以用来允许通过特定IP地址访问网站。

此示例阻止了来自任何地方的流量,除了198.51.100.24.

1[label /var/www/html/.htaccess]
2RewriteCond %{REMOTE_ADDR} !^(198\.51\.100\.24)$
3RewriteRule (.*) - [F,L]

整个规则说,如果请求资源的IP地址不是198.51.100.24,那么不要允许访问。

简而言之:

  • %{REMOTE_ADDR} 是地址字符串
  • !^(198\.51\.100\.24)$ 否定了 IP 地址. \ 背影逃避了 . 点,因为否则,它们作为用于匹配任何字符的元字符。

如果您更愿意从特定地址中 ** 阻止** 访问,请使用以下方法:

1[label /var/www/html/.htaccess]
2RewriteCond %{REMOTE_ADDR} ^(198\.51\.100\.24)$
3RewriteRule (.*) - [F,L]

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

结论

在本教程中,我们使用了.htaccess 文件来与 RewriteRuleRewriteCond 指令一起工作. 使用 rewrite 规则有很多原因,以下资源详细介绍了 mod_rewrite 模块的功能:

mod_rewrite模块是Apache网页服务器的一个关键组成部分,你可以用它做很多事情,但是,事情并不总是按计划进行,当发生这种情况时,你可能会发现自己有一个重定向循环或一个模糊的500禁止错误。

Published At
Categories with 技术
Tagged with
comments powered by Disqus