专栏首页云计算教程系列如何在CentOS 7上为Apache设置mod_rewrite
原创

如何在CentOS 7上为Apache设置mod_rewrite

介绍

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

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

准备

一台已经设置好可以使用sudo命令的非root账号的CentOS服务器,并且已开启防火墙。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器

第1步 - 安装Apache

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

sudo yum install httpd

出现Is this ok [y/d/N]:消息提示时,键入YENTER按键以授权安装。

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

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_rewriteApache模块默认启用。我们将验证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中,以dot(.)开头的文件被视为隐藏。

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

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

找到该<Directory /var/www/html>部分并将AllowOverride指令更改NoneAll

. . .
<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

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

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指令
  • 模式:与所需字符串匹配的PCRE(Perl兼容正则表达式)。
  • 替换:匹配请求应发送到何处
  • [ Flags ]:修改规则的可选参数。有关可用标志及其含义的更多信息,请参阅Apache关于重写标志的文档。

RewriteRulemod_rewrite指令的主力,这就是我们在本教程中主要关注它的原因。

第5步 - 探索RewriteCond语法

RewriteCond指令允许我们为重写规则添加条件。重写条件包括以下结构:

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

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

第6步 - 设置文件

我们将设置一个基本的重写规则,允许用户访问about.html页面而无需在Web浏览器的地址栏中键入文件扩展名(.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

你应该看到一个关于我们的白页。如果从地址栏中删除.html并重新加载页面,则会收到404 Not Found错误。Apache只能通过其完整文件名访问组件,但我们可以使用重写规则对其进行更改。

第7步 - 设置RewriteRule

我们希望访问者关于我们页面访问它而无需键入.html。为此,我们将创建一个规则。

打开.htaccess文件:

sudo vi /var/www/html/.htaccess

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

RewriteRule ^about$ about.html [NC]

保存并退出该文件。

访问者现在可以使用http://server_domain_or_IP/aboutURL 访问“ 关于我们”页面。

我们来看看重写规则:

^about$用作从URL匹配的模式,以及用户在浏览器中键入的内容。 我们的示例使用几个元字符来确保该术语仅存在于URL中的特定位置:

  • server_domain_or_IP/剥离后^表示URL的开头。
  • & 表示URL的结尾

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

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

  • 服务器 or_IP / about
  • 服务器 or_IP /关于
  • 服务器 or_IP / ABOUT

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

常见模式

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

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

示例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/womenresults.php?item=shoes&type=women

例1B:匹配选项

在某些情况下,我们可能希望将查询字符串概括为包含不同类型的鞋子。我们可以通过以下方式完成此任务:

  • 使用垂直管道指定一系列选项|,布尔“OR”运算符
  • 使用匹配对匹配进行()分组,然后使用$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。我们想要映射以下网址:

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指令的使用。如果重写条件的计算结果为true,那么Apache会考虑跟在后面的RewriteRule

例2A:默认页面

以前,我们看到Apache通过提供404 Not Found页面来处理无效URL的请求。但是,我们希望将所有格式错误的网址重定向回主页,而不是错误页面。使用条件,我们可以检查所请求的文件是否存在。

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

这将重定向像/admin/random_text/admin/home

让我们剖析上述规则:

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

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

ErrorDocument 404 /error.html

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

例2B:IP地址限制

A 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模块的功能:

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

更多CentOS教程请前往腾讯云+社区学习更多知识。


参考文献:《How To Set Up mod_rewrite for Apache on CentOS 7》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何在Ubuntu 14.04上使用Bower管理前端JavaScript和CSS依赖项

    Bower是前端模块的包管理器,通常由JavaScript和/或CSS组成。它使我们可以轻松搜索,安装,更新或删除这些前端依赖项。

    SQL GM
  • 如何使用fail2ban防御SSH服务器的暴力破解攻击

    对于SSH服务的常见的攻击就是暴力破解攻击——远程攻击者通过不同的密码来无限次地进行登录尝试。当然SSH可以设置使用非密码验证验证方式来对抗这种攻击,例如公钥验...

    SQL GM
  • 在Ubuntu上迁移你的MySQL数据库

    无论是要添加更多空间,评估优化性能的方法,还是希望利用其他存储功能,本教程都将指导您重新迁移MySQL的数据目录。

    SQL GM
  • python爬虫基础

    py3study
  • 亚马逊再开3000+无人店!国内却一半是海水一半是火焰

    2016年Amazon对外宣布即将上线Amazon Go无人实体超市时,很多人认为此举是亚马逊为了在美国黑色星期五促销时抓住消费者眼球。

    罗超频道
  • 用Burpsuite测试移动应用程序

    保护移动应用程序是当今最重要的问题之一, 因此,对移动应用程序的测试已成为一种必要性,不仅向客户提供足够的安全性,而且向公司提供足够的安全性。

    周俊辉
  • JavaScript|数据类型的使用

    每一种计算机语言都有自己的数据结构和数据类型,JavaScript脚本语言中则是采用弱数据类型的方式,即一个数据不必首先做声明,可以在使用或赋值时再确定其数据的...

    算法与编程之美
  • Vue路由Hash模式分析

    Vue-router是Vue的核心组件,主要是作为Vue的路由管理器,Vue-router默认hash模式,即使用URL的Hash来模拟一个完整的URL,当UR...

    WindrunnerMax
  • 【iOS开发】禁用 WebView 放大镜及拷贝粘贴弹出框

    背景: 当你的App中有 WebView 或者有 Text 文本的时候,毫无疑问,系统默认地会在你进行长按的时候,弹出一个框,来让你拷贝、粘贴、剪切文本等,亦...

    KyXu
  • Apache实现反向代理负载均衡

    说到负载均衡LVS这套技术,有很多种实现方法。 本文所说,主要就是利用apache服务器实现反向代理,实现负载均衡。 首先,传统的正向代理如下图所示,正如我们用...

    用户1154259

扫码关注云+社区

领取腾讯云代金券