URL 重写是将页面映射到本站另一页面, 而重定向则是将页面映射到另一主机(域名). 其中临时重定向(R=302)和永久重定向(R=301)都是亲搜索引擎的, 是 SEO 的重要技术. 通过重定向, 浏览器和搜索引擎都意思到页面发生了变化, 从而分别改变地址栏显示的地址和更新搜索引擎索引。
Apache 中的 URL 重写和重定向
AllowOverride all Options FollowSysLinks
开启重写日志
2.4 以下版本
RewriteLog "自定义日志路径" # 设置日志等级 RewriteLogLevel 9
2.4 及其以上版本
LogLevel alert rewrite:trace3
注意: 日志级别越高, 越影响服务器性能. 生产环境下应关闭重写日志.
重写指令
RewriteEngine
RewriteEngine: 是否启用重写引擎. On启用, Off不启用.
RewriteBase
RewriteBase: 设置重写的基准目录. 基准目录的根目录就是网站的根目录.
RewriteCond
RewriteCond: 设置重写条件.
RewriteCond TestString CondPattern [flags]
RewriteCond 指令定义一条规则条件。
在一条 RewriteRule 指令前面可能会有一条或多条 RewriteCond 指令,只有 TestString 符合 CondPattern 时规则才被应用于当前URL处理。
1) TestString是一个纯文本的字符串,除了包含普通的字符外,还可以包括下列的可扩展结构:
$N: RewriteRule 后向引用,其中(0 <= N <= 9) . $N引用紧跟在 RewriteCond 后面的 RewriteRule 中模板中的括号中的模板在当前 URL 中匹配的数据。
%N: RewriteCond 后向引用, 其中(0 <= N <= 9). %N引用最后一个 RewriteCond 的模板中的括号中的模板在当前 URL 中匹配的数据。
${mapname:key|default}:RewriteMap 扩展。
2) CondPattern是条件 pattern, 即一个应用于当前实例TestString 的正则表达式, 即 TestString 将会被计算然后与CondPattern 匹配. 作为一个标准的扩展正则式, CondPattern 有以下补充:
CondPattern中可以使用以下特殊变量:
>CondPattern: 大于, 将 CondPattern 当作一个普通字符串, 将它和 TestString 进行比较, 当T estString 的字符大于CondPattern 为真.=CondPattern: 等于, 将 CondPattern 当作一个普通字符串,将它和TestString进行比较, 当 TestString 与 CondPattern 完全相同时为真. 如果 CondPattern 只是 "" (两个引号紧挨在一起) 此时需 TestString 为空字符串方为真
-d: 是否为目录, 将 TestString 当作一个目录名, 检查它否存在以及是否是一个目录.
-f: 是否是 regular file, 将 TestString 当作一个文件名, 检查它是否存在以及是否是一个 regular 文件.
-s: 是否为长度不为0的 regular文件, 将 TestString 当作一个文件名, 检查它是否存在以及是否是一个长度大于0的 regular 文件.
-l: 是否为 symbolic link, 将 TestString 当作一个文件名, 检查它是否存在以及是否是一个 symbolic link.
-F: 通过 subrequest 来检查某文件是否可访问. 检查 TestString 是否是一个合法的文件, 而且通过服务器范围内的当前设置的访问控制进行访问. 这个检查是通过一个内部 subrequest 完成的, 因此需要小心使用这个功能以降低服务器的性能.
-U: 通过 subrequest 来检查某个 URL 是否存在. 检查 TestString 是否是一个合法的URL, 而且通过服务器范围内的当前设置的访问控制进行访问. 这个检查是通过一个内部 subrequest 完成的, 因此需要小心使用这个功能以降低服务器的性能.
3) [flags]是第三个参数,多个标志之间用逗号分隔。
nocase|NC: 不区分大小写. 在扩展后的 TestString 和 CondPattern 中, 比较时不区分文本的大小写. 注意, 这个标志对文件系统和 subrequest 检查没有影响.
ornext|OR: 建立与下一个条件的或的关系. 默认的情况下,二个条件之间是AND的关系, 用这个标志将关系改为OR. 例如:
RewriteCond %{REMOTE_HOST} ^host1.* [OR] RewriteCond %{REMOTE_HOST} ^host2.* [OR] RewriteCond %{REMOTE_HOST} ^host3.* RewriteRule …
RewriteRule
RewriteRule: 设置重写规则.
RewriteRule Pattern Substitution [flags].
1) Pattern是一个作用于当前 URL 的兼容 perl 的正则表达式. 这里的“当前”是指该规则生效时的 URL 的值。
2) Substitution是当原始 URL 与 Pattern 相匹配时, 用以替代(或替换)的字符串. (RewriteRule 中也会进行一次判断, 被捕获的 URL 是否与 Pattern相匹配)
3) Substitution还可以追加特殊标记[flags]作为 RewriteRule 指令的第三个参数。 Flags 是一个包含以逗号分隔的下列标记的列表:
强制性执行一个外部重定向. 如果code没有指定, 则默认302. 如果需要使用在 300-400 范围内的其他响应代码, 只需在此指定这个数值即可。
另外, 还可以使用下列符号名称之一: temp(默认的), permanent, seeother.
2.forbidden|F(强制 URL 为被禁止的 forbidden )
3.gone|G(强制 URL 为已废弃的 gone )
11.qsappend|QSA(追加请求串 query string append)
此标记强制重写引擎在已有的替换串中追加一个请求串, 而不是简单的替换. 如果需要通过重写规则在请求串中增加信息, 就可以使用这个标记。
12.noescape|NE(在输出中不对URI作转义 no URI escaping)
RewriteRule /foo/(.*) /bar?arg=P1=$1 [R,NE] 可以使’/foo/zed’转向到一个安全的请求’/bar?arg=P1=zed’.
13.passthrough|PT(移交给下一个处理器 pass through)
14.skip|S=num(跳过后继的规则 skip)
15.env|E=variable:value(设置环境变量 environment variable)
16.cookie|CO=NAME:VAL:domain[:lifetime[:path]](设置cookie)
在客户端浏览器上设置一个cookie. cookie 的名称是 NAME, 值是 VAL. domain字段是该 cookie 的域, 比如'.apache.org', 可选的 lifetime 是 cookie 生命期的分钟数, 可选的 path 是 cookie 的路径。
在.htaccess 文件中配置重写规则
- 如果.htaccess在网站根目录下, 那么RewriteRule捕获的 URI 是subdir1/subdir2/subdir3.
- 如果.htaccess在 subdir1 目录下, RewriteRule捕获的 URI 是subdir2/subdir3.
RewriteRule重写 URI 后的基准目录也是以.htaccess所在的目录为准. 例如: 访问 http://example.com/foo
RewriteRule ^foo$ bar.php [L]
例1:
<IfModule mod_rewrite.c># 启用rewrite引擎RewriteEngine On# 重写规则: 匹配任意以htm后缀的文件, 将htm替换成php. ^(.*)\.htm$ 是一个正则表达式, 表示需要重写的部分, 此处指以任意字符开头, 以.htm结尾的部分. $1.php 是一个重写规则, $1 表示匹配到正则表达式中第一个子模式的字符串. [NC]: 表示重写规则如何应用, 该处表示不区分大小写. 整条规则即重写以任意字符开头, 以.htm结尾的部分, 重写为由匹配到的第一个子模式字符串和.php拼接成的字符串。RewriteRule ^(.*)\.htm$ $1.php [NC]</IfModule>
IfModule 命令用于判断是否安装了 mod_rewrite 模块。
<IfModule mod_rewrite.c>RewriteEngine On# 设置目录级重写的基准URIRewriteBase /subdir1/RewriteRule ^(.*)\.htm$ $1.php [NC,L,R]</IfModule>
- RewriteBase设置了重写的基准目录. 如果上例中.htaccess位于网站根目录下, 访问的 http://example.com/foo.htm, 原本重写后的基准目录是网站根目录/, 设置了RewriteBase后变为/subdir1/, 重写后实际访问 http://example.com/subdir1/foo.php.
- 规则标志L: 表示如果可以匹配本条规则, 则不再继续往下匹配.
- 规则标志R: 表示临时重定向, 即 302, 相当于[R=302]。
<IfModule mod_rewrite.c><IfModule mod_rewrite.c>RewriteEngine OnRewriteCond %{HTTP_HOST} (localhost:81)RewriteRule ^(.*) http://localhost:82 [R=301]</IfModule>
- [R=301]: 表示永久性重定向, 用户发送的所有请求都会被发送到新域名处理,永久重定向到另一个域名使用了绝对 URI, 因此不用再设置 RewriteBase。
- %{HTTP_HOST}:表示引用 Apache 服务器变量 HTTP_HOST。
- 该条RewriteCond 表示判断 HTTP_HOST 是否是 localhost:81。
在httpd.conf 中配置重写规则
Nginx
Nginx 的 URL 重写功能不需要额外的支持. Nginx 本身只支持在服务器配置文件中配置 URL 重写规则, 不支持 .htaccess 文件. 但可以通过在服务器配置文件中引入外部文件的方式, 实现对 .htaccess 文件的支持. 这会严重影响 Nginx 的性能。
重写指令
rewrite
rewrite regex replacement flag
- last: 相当于 Apache 中的L标记。
- break: 终止匹配, 不再匹配后面的规则。
- redirect: 临时重定向, 返回 302。
- permanent: 永久性重定向, 返回 301。
rewrite ^(.*)\.html$ $1.php last;
if 指令
if (condition){...}
condition中可以包含如下判断表示:
- ~: 区分大小写进行匹配
- ~*: 不区分大小写进行匹配
- !~: 区分大小写进行非匹配
- !~*: 不区分大小写进行非匹配
- -f: 如果文件存在
- !-f: 如果文件不存在
- -d: 如果目录存在
- !-d: 如果目录不存在
- -e: 如果文件或目录存
- !-e: 如果文件或目录不存在
- -x: 如果文件可执行
- !-x: 如果文件不可执行
location ~ \.html$ {if (!-f $request_filename){rewrite (.*)\.html$ $1.php last;}}
return 指令
return code复制代码
return 403;
location 指令
location [flags] regex
flags 包括:
- ~: 执行一个正则匹配, 区分大小写
- ~*: 执行一个正则匹配, 不区分大小写
- ^~: 表示普通字符匹配. 使用前缀匹配成功. 如果匹配成功, 则不再匹配其他 location.
- =: 进行普通字符完全匹配.
- =的优先级最高. 匹配成功后, 不再匹配其他项.
- ^~类型表达式. 匹配成功后, 不再匹配其他项.
- ~和~*. 如果有多个 location 的正则匹配.
- 常规字符串匹配类型, 按前缀匹配.
rewrite_log 指令
rewrite_log on|off
set 指令
set variable value
Nginx 内置的全局变量
$args: 这个变量等于请求行中的参数, 同 $query_string.- $content_length: 请求头中的 Content-length 字段.
- $content_type: 请求头中的 Content-Type 字段.
- $document_root: 当前请求在 root 指令中指定的值.
- $host: 请求主机头字段,否则为服务器名称.
- $http_user_agent: 客户端 agent 信息.
- $http_cookie: 客户端 cookie 信息.
- $limit_rate: 这个变量可以限制连接速率.
- $request_method: 客户端请求的动作,通常为 GET 或 POST.
- $remote_addr: 客户端的 IP 地址.
- $remote_port: 客户端的端口.
- $remote_user: 已经经过 Auth Basic Module 验证的用户名.
- $request_filename: 当前请求的文件路径, 由 root 或 alias 指令与 URI 请求生成.
- $scheme: HTTP 方法(如 http, https).
- $server_protocol: 请求使用的协议, 通常是HTTP/1.0 或 HTTP/1.1.
- $server_addr: 服务器地址, 在完成一次系统调用后可以确定这个值.
- $server_name: 服务器名称.
- $server_port: 请求到达服务器的端口号.
- $request_uri: 包含请求参数的原始 URI, 不包含主机名, 如: ”/foo/bar.php?arg=baz”.
- $uri: 不带请求参数的当前 URI, $uri 不包含主机名, 如 "/foo/bar.html".
- $document_uri: 与$uri相同.
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/7234/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料