介绍
在本教程中,我们会激活并学习如何管理URL中使用的Apache2的重写mod_rewrite
模块。 此工具允许我们以更清晰的方式重写URL,将人类可读的路径转换为对代码友好的查询字符串。
本指南分为两个部分:第一个设置示例Web应用程序,第二个说明常用的重写规则。
先决条件
要遵循本教程,您需要:
- 一个新鲜的Ubuntu 14.04 Droplet
- sudo的一个非root用户,您可以通过以下第2步和3设置本教程
第1步 - 安装Apache
在这一步中,我们将使用称为一个内置的安装程序包 apt-get
。 它大大简化了管理,并有助于清洁安装。
首先,更新系统的包索引。 这将确保旧的或过时的包不会干扰安装。
sudo apt-get update
Apache2是前面提到的HTTP服务器和世界上最常用的。 要安装它,请运行以下命令:
sudo apt-get install apache2
有关Nginx的和的Apache2之间的差异,这两个最流行的开源Web服务器,请参阅这篇文章 。
第2步 - 启用mod_rewrite
现在,我们需要激活mod_rewrite
。
sudo a2enmod rewrite
这将激活模块或提醒您模块已经生效。 要使这些更改生效,请重新启动Apache。
sudo service apache2 restart
第3步 - 设置.htaccess
在本节中,我们将设置一个.htaccess
较简单的重写规则管理文件。
一个.htaccess
文件允许我们修改我们的重写规则,而无需访问服务器的配置文件。 出于这个原因, .htaccess
是Web应用程序的安全至关重要。 文件名前面的时间段确保文件被隐藏。
在开始之前,我们需要设置并保护一些其他设置。
首先,请允许在变化.htaccess
文件。 使用打开默认的Apache配置文件nano
或您喜爱的文本编辑器。
sudo nano /etc/apache2/sites-enabled/000-default.conf
在这个文件中,你会发现<VirtualHost *:80>
第1行块内的块,添加以下块:
/etc/apache2/sites-available/default<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
您的文件现在应该匹配以下。 确保所有块都正确缩进。
/etc/apache2/sites-available/default<VirtualHost *:80>
<Directory /var/www/html>
. . .
</Directory>
. . .
</VirtualHost>
要使这些更改生效,请重新启动Apache。
sudo service apache2 restart
现在,创建.htaccess
文件。
sudo nano /var/www/html/.htaccess
在新文件的顶部添加此行头,以激活RewriteEngine
。
/var/www/html/.htaccessRewriteEngine on
保存并退出文件。
为了确保其他用户可能只能读取您.htaccess
,运行以下命令来更新权限。
sudo chmod 644 /var/www/html/.htaccess
你现在有一个操作.htaccess
文件,以管理Web应用程序的路由规则。
第4步 - 设置文件
在本节中,我们将设置一个基本的URL重写,将漂亮的URL转换为实际的代码路径。 具体而言,我们将允许用户访问example.com /about
。
我们将创建一个文件名为开始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>
您可以在访问你的web应用your_server_ip /about.html
或example.com /about.html
。 现在可以看到仅有about.html
是可访问的; 如果您尝试访问your_server_ip /about
,你会得到一个未找到错误。 我们希望用户访问about
替代。 我们的重写规则将允许这个功能。
打开.htaccess
文件。
sudo nano /var/www/html/.htaccess
在第一行之后,添加以下内容。
/var/www/html/.htaccessRewriteRule ^about$ about.html [NC]
您的文件现在应该与以下内容相同。
/var/www/html/.htaccessRewriteEngine on
RewriteRule ^about$ about.html [NC]
恭喜。 现在,您可以访问example.com /about
在您的浏览器!
这是一个很好的简单示例,显示了所有重写规则遵循的一般语法。
^about$
是获取从URL匹配的字符串。 也就是说,它是浏览器在浏览器中键入的内容。 我们的示例使用了几元字符 。
-
^
表示URL的开始,之后example.com /
被剥夺。 -
$
表示URL的末尾 -
about
字符串“约”匹配
about.html
是用户访问的实际路径; 也就是说,Apache将仍然服务于about.html
文件。
[NC]
是在URL忽略大写的标志 。
有了上面的规则,以下网址将指向about.html
:
-
example.com /about
-
example.com /About
-
example.com /about.html
以下不会:
-
example.com /about/
-
example.com /contact
常见模式
在本节中,我们将展示一些常用的指令。
您的Web应用程序正在运行,并通过保护治理.htaccess
文件。 最简单的例子包括在上面。 我们将在本节中探讨另外两个例子。
如果您愿意,可以在结果路径中设置示例文件,但本教程不包括创建HTML和PHP文件; 只是重写的规则。
示例1:使用RewriteRule简化查询字符串
所有RewriteRule
S按以下格式恪守:
RewriteRule pattern substitution [flags]
- 重写规则 :指定指令
RewriteRule
- 图案 :一个正则表达式所需的字符串相匹配
- 替代 :路径实际的URL
- 标志 :可以修改规则的可选参数
Web应用程序通常使用查询字符串 ,利用其追加到一个URL的?
问号,并使用分隔&
符号。 匹配重写规则时将忽略这些。 但是,在页之间传递数据时可能需要查询字符串。 例如,用PHP编写的搜索结果页面可以使用类似于以下内容的内容:
http://example.com/results.php?item=shirt&season=summer
在这个例子中,我们想简化为:
http://example.com/shirt/summer
示例1A:简单替换
使用重写规则,我们可以使用以下:
/var/www/html/.htaccessRewriteRule ^shirt/summer$ results.php?item=shirt&season=summer
以上是相当不言自明的,因为它实际上映射shirt/summer
到results.php?item=shirt&season=summer
。 这实现了我们期望的效果。
示例1B:匹配选项
但是,我们想将其概括为包括所有季节。 所以,我们将做以下:
- 使用指定一系列选项
|
布尔,意为“OR” - 集团使用匹配
()
然后引用使用组$1
,用1
第一个匹配的组
重写规则现在变成:
/var/www/html/.htaccessRewriteRule ^shirt/(summer|winter|fall|spring) results.php?item=shirt&season=$1
上面显示的规则的URL匹配shirt/
后面指定的季节。 该季节使用分组()
然后与参考$1
在随后的路径。 这意味着,例如:
http://example.com/shirt/winter
变为:
http://example.com/results.php?item=shirt&season=winter
这也实现了期望的效果。
示例1C:匹配字符集
然而,我们也想指定任何类型的项目,而不是仅仅在的超文本链接/shirt
。 所以,我们将做以下:
- 编写匹配所有字母数字字符的正则表达式 。 括号表达式
[]
任何字符匹配它的内部,而+
任意数量的括号内指定的字符相匹配 - 组的匹配,并且与引用它
$2
的文件中的第二可变
/var/www/html/.htaccessRewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2
以上将转换,例如:
http://example.com/pants/summer
至:
http://example.com/results.php?item=pants&season=summer
示例1D:传递查询字符串
本节不介绍任何新概念,但解决可能出现的问题。 使用上面的例子,假设我们想重定向http://example.com/pants/summer
,但会通过额外的查询字符串?page=2
。 我们想要以下:
http://example.com/pants/summer?page=2
映射到:
http://example.com/results.php?item=pants&season=summer&page=2
如果你要试图访问我们的当前设置上面的URL,你会发现,查询字符串page=2
迷路了。 这是很容易使用附加的固定QSA
标志。 修改重写规则以匹配以下内容,并将实现所需的行为。
/var/www/html/.htaccessRewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2 [QSA]
示例2:使用逻辑添加条件
RewriteCond
让我们添加条件,我们的重写规则。 所有RewriteCond
小号恪守的格式如下:
RewriteCond TestString Condition [Flags]
- RewriteCond指令 :指定
RewriteCond
指令 - 的TestString:要测试的字符串对
- 条件 :要匹配的模式
- 标志 :可以修改条件的可选参数
如果RewriteCond
计算结果为真,则RewriteRule
后立即将予以考虑。
示例2A:默认页
在虚构的管理面板中,我们可能要将所有格式不正确的网址返回主页,而不是用404问候用户。使用条件,我们可以检查所请求的文件是否存在。
/var/www/html/.htaccessRewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/(.*)$ /admin/home
这将重定向像/admin/blargh
到/admin/home
。
用上面的:
-
%{REQUEST_FILENAME}
是检查字符串 -
!-f
使用!
不运算符的文件名 -
RewriteRule
重定向所有请求回/admin/home
需要注意的是一个更加语法和技术上正确的方法是定义404 ErrorDocument
。
/var/www/html/.htaccessErrorDocument 404 /error.html
示例2B:IP访问限制
尽管这也可以用其他方法来实现,一个RewriteCond
可用于限制访问一个IP或IP地址的集合。
这个例子阻止流量来自世界各地,除了 12.34.56.789。
/var/www/html/.htaccessRewriteCond %{REMOTE_ADDR} !^(12\.34\.56\.789)$
RewriteRule (.*) - [F,L]
这个例子很简单的否定例3从旧的mod_rewrite的文章 。 整个声明说:“如果地址不 12.34.56.789,不允许访问”。
简而言之:
-
%{REMOTE_ADDR}
是地址字符串 -
!^(12\.34\.56\.789)$
逃脱所有.
有段\
反斜线和使用否定的IP地址!
- 所述
F
标志禁止访问,和L
标志表示这是在最后一个规则来运行,如果执行
如果您想阻止 12.34.56.789,用这个来代替:
/var/www/html/.htaccessRewriteCond %{REMOTE_ADDR} ^(12\.34\.56\.789)$
RewriteRule (.*) - [F,L]
你可以找到更多重写规则,以及如何防止热链接,在原始文章的和第2部分 。
结论
mod_rewrite
可以有效地使用,以确保人类可读的网址。 该.htaccess
文件本身有许多更多的用途不是简单地该模块,但是,应该指出的是,许多其他的Apache模块可以被安装到扩展其功能。
还有其他资源细节的能力mod_rewrite
:
mod_rewrite
是Web应用安全的关键模块,但有时可以重定向循环或无处不在,模棱两可最终500 forbidden
错误。 有关调试技巧.htaccess
,看到这个计算器职位 。
重写规则使用正则表达式编写。 要成为一个专家,参考本教程的所有正则表达式 。
对于你的正则表达式模式快速分析,这里是一个在线调试器 ,可以提供即时反馈和您的正则表达式模式的现场演绎。