如何在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 条评论
登录 后参与评论

相关文章

来自专栏咸鱼不闲

post和get的区别,面试经常被问到!(二)

3712
来自专栏古时的风筝

C/C++中动态链接库的创建和调用

DLL 有助于共享数据和资源。多个应用程序可同时访问内存中单个DLL 副本的内容。DLL 是一个包含可由多个程序同时使用的代码和数据的库。下面为你介绍C/C++...

28210
来自专栏三木的博客

Linux shell 程序设计3——命令行程序

1、date:显示、设置系统的日期和时间。 $date 2011年 01月 30日 星期日 14:43:35 CST $date 012309232011 执行...

2086
来自专栏抠抠空间

【Django错误】OSError: raw write() returned invalid length 14 (should have been between 0 and 7)

错误环境 使用Django框架创建完models类的之后,用python manage.py migrate命令来生成数据库表的时候出错 错误代码 Operat...

3465
来自专栏叁金大数据

自学Python四 爬虫基础知识储备

  首先,推荐两个关于python爬虫不错的博客:Python爬虫入门教程专栏   和 Python爬虫学习系列教程 。写的都非常不错,我学习到了很多东西!在此...

1071
来自专栏程序员互动联盟

【专业技术】揭秘安卓浏览器如何注入javascript脚本

Android中向webview注入js代码可以通过webview.loadUrl("javascript:xxx")来实现,然后就会执行javascript后...

5364
来自专栏Spark学习技巧

Kafka源码系列之如何删除topic

本文依然是以kafka0.8.2.2为例讲解 一,如何删除一个topic 删除一个topic有两个关键点: 1,配置删除参数 delete.topic.enab...

4529
来自专栏python开发教学

【Django错误】OSError: raw write() returned invalid length 14 (should have been between 0 and 7)

错误环境 使用Django框架创建完models类的之后,用python manage.py migrate命令来生成数据库表的时候出错 错误代码 Operat...

3917
来自专栏Linux驱动

1.Linux电源管理-休眠与唤醒

当我们休眠时,如果想唤醒,则需要添加中断唤醒源,使得在休眠时,这些中断是设为开启的,当有中断来,则会退出唤醒,常见的中断源有按键,USB等.

5682
来自专栏菩提树下的杨过

ZooKeeper 笔记(3) 实战应用之【统一配置管理】

大型应用通常会按业务拆分成一个个业务子系统,这些大大小小的子应用,往往会使用一些公用的资源,比如:需要文件上传、下载时,各子应用都会访问公用的Ftp服务器。如果...

5115

扫码关注云+社区

领取腾讯云代金券