php

apache重写规则

2018-07-16  本文已影响206人  傅二毛

Aapache重写规则

.htaccess叫分布式配置文件,.htaccess文件的作用在于当浏览器通过uri访问到服务器某个文件夹或文件时,我们可以决定这个uri是否访问uri指定资源或者拒绝访问。并且通过一个十分友好的uri吸引用户进来,并且通过.htaccess文件把用户导向服务器指定的访问位置。它提供了针对目录改变配置的方法——在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。并且子目录中的指令会覆盖更高级目录或者主服务器配置文件中的指令。说的通俗点,他就是:一个更改服务器配置的‘文本’文件。一般来说,如果你的虚拟主机使用的是Unix或Linux系统,或者任何版本的Apache网络服务器,从理论上讲都是支持.htaccess的。他可以实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等等。

前提

必须开启apache里面的重写模块!

# 找到下面这行代码,取消其注释符号 ‘#’。
# LoadModule reqtimeout_module libexec/apache2/mod_reqtimeout.so

.htaccess基本语法介绍

基本语句

语句 含义
RewriteEngine on 开启apache重写功能
RewriteBase / 设置重写根目录
RewriteCond rewrite condition 重写条件,匹配符合条件——正则的请求
RewriteRule 重定向

RewriteBase

RewriteEngine on
RewriteBase /
RewriteRule ^(.*)\.htm$ $1.php [R,NC,L]

RewriteBase定义了重写基准目录。
例如,如果你将虚拟站点设置在/var/www目录下,删除这行将会导致重定向到http://yourdomain.com/var/www/1.php。显然这是找不到的,而且你也不会希望用户看见你的服务器的目录结构。
再举个例子,如果RewriteBase /base/,那么将会重定向到http://yourdomain.com/base/1.php
对于重写基准目录,我们还可以通过将$1.php变成/$1.php实现直接变换,这时就可以将RewriteBase省略。

RewriteCond说明

语法

【说明 】定义重写发生的条件
【语法】 RewriteCond 【TestString】 【CondPattern】 [flags]
【作用域】 server config, virtual host, directory, .htaccess
【覆盖项】 FileInfo
【状态】 扩展(E)
【模块】 mod_rewrite

注意事项

  1. 可以在CondPattern串的开头使用’!'(惊叹号)来指定不匹配。

  2. CondPatterns有若干特殊的变种。除了正则表达式的标准用法,还有下列用法:

    ‘<CondPattern’(词典顺序的小于)
    将CondPattern视为纯字符串,与TestString按词典顺序进行比较。如果TestString小于CondPattern则为真。
    ‘>CondPattern’(词典顺序的大于)
    将CondPattern视为纯字符串,与TestString按词典顺序进行比较。如果TestString大于CondPattern则为真。
    ‘=CondPattern’(词典顺序的等于)
    将CondPattern视为纯字符串,与TestString按词典顺序进行比较。如果TestString等于CondPattern(两个字符串逐个字符地完全相等)则为真。如果CondPattern是”"(两个双引号),则TestString将与空字符串进行比较。
    ‘-d’(目录)
    将TestString视为一个路径名并测试它是否为一个存在的目录。
    ‘-f’(常规文件)
    将TestString视为一个路径名并测试它是否为一个存在的常规文件。
    ‘-s’(非空的常规文件)
    将TestString视为一个路径名并测试它是否为一个存在的、尺寸大于0的常规文件。
    ‘-l’(符号连接)
    将TestString视为一个路径名并测试它是否为一个存在的符号连接。
    ‘-x’(可执行)
    将TestString视为一个路径名并测试它是否为一个存在的、具有可执行权限的文件。该权限由操作系统检测。
    ‘-F’(对子请求存在的文件)
    检查TestString是否为一个有效的文件,而且可以在服务器当前的访问控制配置下被访问。它使用一个内部子请求来做检查,由于会降低服务器的性能,所以请谨慎使用!
    ‘-U’(对子请求存在的URL)
    检查TestString是否为一个有效的URL,而且可以在服务器当前的访问控制配置下被访问。它使用一个内部子请求来做检查,由于会降低服务器的性能,所以请谨慎使用!
    
  3. 还可以在CondPattern之后追加特殊的标记[flags]作为RewriteCond指令的第三个参数。flags是一个以逗号分隔的以下标记的列表:

    • ‘nocase|NC’(忽略大小写)

      它使测试忽略大小写,扩展后的TestString和CondPattern中’A-Z’ 和’a-z’是没有区别的。此标记仅用于TestString和CondPattern的比较,而对文件系统和子请求的检查不起作用。

    • ‘ornext|OR’(或下一条件)

      它以OR方式组合若干规则的条件,而不是隐含的AND。

    RewriteCond %{REMOTE_HOST} ^host1.* [OR]
    RewriteCond %{REMOTE_HOST} ^host2.* [OR]
    RewriteCond %{REMOTE_HOST} ^host3.*
    RewriteRule … 针对这3个主机的规则集 …如果不用这个标记,你就必须要书写三次条件/规则对。
    

RewriteRule配置参数

语句 含义
R 强制外部重定向;R=301 永久重定向、R=302 临时重定向
F 禁止URL,返回403 http状态码
G 强制URL为GONE,返回410 http状态码
P 强制使用代理转发
L 表明当前规则是最后一条规则,停止分析以后的规则重写
N 重新从第一条规则开始运行重写过程
C 与下一条规则关联
T=MIME-type(force MIME type) 强制MIME类型
NS 只是用于不是内部的子请求
NC 不区分大小写
QSA 追加请求字符串
NE 不再输出转义特殊字符 %3d$1 等价于 =$1

生效条件

【说明 】定义重写发生的条件
【语法】 RewriteCond 【TestString】 【CondPattern】 [flags]
【作用域】 server config, virtual host, directory, .htaccess
【覆盖项】 FileInfo
【状态】 扩展(E)
【模块】 mod_rewrite

RewriteCond指令定义了规则生效的条件,即在一个RewriteRule指令之前可以有一个或多个RewriteCond指令。条件之后的重写规则仅在当前URIPattern匹配并且满足此处的条件(TestString能够与CondPattern匹配)时才会起作用。

  1. RewriteRule反向引用 ,引用方法是:$N (0 <= N <= 9)引用当前(带有若干RewriteRule指令的)RewriteCond中的与Pattern匹配的分组成分(圆括号!)。
  2. RewriteCond反向引用 ,引用方法是:%N (1 <= N <= 9)引用当前若干RewriteCond条件中最后符合的条件中的分组成分(圆括号!)。
  3. RewriteMap扩展 ,引用方法是:${mapname:key|default} 细节请参见RewriteMap 指令。
  4. 服务器变量 ,引用方法是:%{NAME_OF_VARIABLE} NAME_OF_VARIABLE可以是下节apache环境变量列出的字符串之一:

apache环境变量

获取环境变量

在上一节中讲述了 %{} 代表获取环境变量;可以获取的环境变量中的任何变量。具体内容还需要参见官方文档中——重写模块,要分析环境变量最好的方法phpinfo();访问地址写全一点http://www.fuermao.com/index.php?1111#111,环境变量的类型如下表(phpinfo()所获取的并不是特别全):

apache环境变量
HTTP Header Information

官方其他参数说明

IS_SUBREQ
如果正在处理的请求是一个子请求,它将包含字符串”true”,否则就是”false”。模块为了解析URI中的附加文件,可能会产生子请求。
API_VERSION
这是正在使用中的Apache模块API(服务器和模块之间内部接口)的版本, 其定义位于include/ap_mmn.h中。此模块API版本对应于正在使用的Apache的版本(比如在Apache 1.3.14的发行版中这个值是19990320:10)。 通常,对它感兴趣的是模块的开发者。
THE_REQUEST
这是由浏览器发送的完整的HTTP请求行(比如:”GET /index.html HTTP/1.1″)。它不包含任何浏览器发送的其它头信息。
REQUEST_URI
这是在HTTP请求行中所请求的资源(比如上述例子中的”/index.html”)。
REQUEST_FILENAME
这是与请求相匹配的完整的本地文件系统的文件路径名。
HTTPS
如果连接使用了SSL/TLS,它将包含字符串”on”,否则就是”off”(无论mod_ssl是否已经加载,该变量都可以安全的使用)。

注意事项

  1. SCRIPT_FILENAME和REQUEST_FILENAME包含的值是相同的——即Apache服务器内部的request_rec结构中的filename字段。 第一个就是大家都知道的CGI变量名,而第二个则是REQUEST_URI(request_rec结构中的uri字段)的一个副本。

  2. 特殊形式:%{ENV:variable} ,其中的variable可以是任意环境变量。它是通过查找Apache内部结构或者(如果没找到的话)由Apache服务器进程通过getenv()得到的。

  3. 特殊形式:%{SSL:variable} ,其中的variable可以是一个SSL环境变量的名字,无论mod_ssl模块是否已经加载都可以使用(未加载时为空字符串)。比如:%{SSL:SSL_CIPHER_USEKEYSIZE}将会被替换为128。

  4. 特殊形式:%{HTTP:header} ,其中的header可以是任意HTTP MIME头的名称。它总是可以通过查找HTTP请求而得到。比如:%{HTTP:Proxy-Connection}将被替换为Proxy-Connection:HTTP头的值。

  5. 预设形式:%{LA-U:variable} ,variable的最终值在执行一个内部(基于URL的)子请求后确定。 当需要使用一个目前未知但是会在之后的过程中设置的变量的时候,就可以使用这个方法。例如,需要在服务器级配置(httpd.conf文件)中根据REMOTE_USER变量进行重写, 就必须使用%{LA-U:REMOTE_USER}。因为此变量是由URL重写(mod_rewrite)步骤之后的认证步骤设置的。 但是另一方面,因为mod_rewrite是通过API修正步骤来实现目录级(.htaccess文件)配置的, 而认证步骤先于API修正步骤,所以可以用%{REMOTE_USER}。

  6. 预设形式:%{LA-F:variable} ,variable的最终值在执行一个内部(基于文件名的)子请求后确定。 大多数情况下和上述的LA-U是相同的。

CondPattern是条件模式,即一个应用于当前TestString实例的正则表达式。TestString将被首先计算,然后再与CondPattern匹配。

调试重写模块

关于调试信息

关于调试这部分由于不能够直接打印和输出,所以需要在apache的日志中去查找相关信息。apache的日志大致分为两类,如:

日志一般都在httpd.conf文件的相关位置有路径,当然可以改变日志记录的路径;

# 错误日志
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here.  If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
# 这个地方时我修改后的错误日志记录信息位置
ErrorLog "/Users/futianyu/log/apache/error_log"

# 这个地方是日志记录级别:一共有8个级别;
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
# 暂时注释掉
# LogLevel warn
# 重写调试时打开,因为要调试重写模块
LogLevel info rewrite:trace5

#
# The location and format of the access logfile (Common Logfile Format).
# If you do not define any access logfiles within a <VirtualHost>
# container, they will be logged here.  Contrariwise, if you *do*
# define per-<VirtualHost> access logfiles, transactions will be
# logged therein and *not* in this file.
# 这个地方就是访问日志,当然我也改了路径了;
CustomLog "/Users/futianyu/log/apache/access_log" common

设置日志输出级别

此处我们需要查看的是重写模块调试时的错误信息,给个官方文档的连接;重写模块日志记录中的Per-module logging部分有说明;改了写配置文件需要重启httpd服务器,不然不会生效。在上面的代码中文档已经给出了日志级别的说明:debug, info, notice, warn, error, crit,alert, emerg

示例

示例一

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$
RewriteCond %{REQUEST_URI} !^/blog/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /blog/$1

# 没有输入文件名的默认到到首页
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$
RewriteRule ^(/)?$ blog/index.php [L]

第一部分 重写规则

第二部分 重写规则

正确答案
RewriteEngine On
RewiteBase /
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/blog/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ blog/$1

# 没有输入文件名的默认到到首页
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ [NC]
RewriteRule ^(/)?$ blog/index.php [L]

示例二 将.htm页面映射到.php

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.*)\.htm$ $1.php [NC]

注意事项:

示例三 长短地址转换

若访问http://mysite/grab?file=my.zip
如何实际访问至http://mysite/public/files/download/download.php?file=my.zip

RewriteEngine On
RewriteRule ^grab /public/files/download/download.php

示例四 支持多域名访问

现在假设你有域名domain-one.com和domain-two.com,并且在服务器根目录有对应文件夹one和two,那么通过下面的改写就能让Apache同时接受者两个域名的请求:

RewriteCond %{HTTP_HOST} domain-one.com
RewriteCond %{REQUEST_URI} !^/one
RewriteRule ^(.*)$ /one/$1 [L]

RewriteCond %{HTTP_HOST} domain-two.com
RewriteCond %{REQUEST_URI} !^/two
RewriteRule ^(.*)$ /two/$1 [L]

示例五 去掉www

Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,NC,L]

示例六 加上www

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(.*)$
RewriteRule (.*) http://www\.%1/$1 [R=301,L]

参考资料

《.htaccess 基础教程(四)Apache RewriteCond 规则参数》 http://www.cnblogs.com/52php/p/5670199.html

《 .htaccess技巧: URL重写(Rewrite)与重定向(Redirect)》 https://blog.csdn.net/newjueqi/article/details/12014673 维摩诘

上一篇下一篇

猜你喜欢

热点阅读