什么是URL重定向:
URL重定向(URL redirection,或称网址重定向或网域名称转址),是指当使用者浏览某个网址时,将他导向到另一个网址的技术。
重写和重定向的区别:
重定向 :浏览器知道页面位置发生变化,从而改变地址栏显示的地址搜索引擎意识到页面被移动了,从而更新搜索引擎索引,将原来失效的链接从搜索结果中移除
临时重定向(R=302)和永久重定向(R=301)都是亲搜索引擎的,是SEO的重要技术
重写:用于将页面映射到本站另一页面,若重写到另一网络主机(域名),则按重定向处理
URL重定向模块开启:
如果要想用到rewrite模块,必须先安装或加载rewrite模块。
方法有两种
一种是编译apache的时候就直接安装rewrite模块,
二是如果编译apache时以DSO模式安装apache的,可以利用源码和apxs来安装rewrite模块。
URl重定向配置方式:
1.可基于服务器级
1.1 (httpd.conf),在httpd.conf中写,这种写法适合有服务器完整权限的网站管理员,
RewriteEngine on来打开rewrite功能;
1.2 另一种是在局部 virtualhost 里 利用RewriteEngine on来打开rewrite功能,
需要注意的是,必须在每个virtualhost里用RewriteEngine on来打开rewrite功能。
否则virtualhost里没有RewriteEngine on它里面的规则也不会生效。
写法大概如下:
<VirtualHost *:80>
DocumentRoot "/websites/www"
ServerName localhost
RewriteEngine On
RewriteRule ^index\.html$ index.php [L]
</VirtualHost>
2.目录级
(.htaccess)在网站目录中使用.htaccess,这种方法适合采用虚拟主机形式的网站管理员,
.htaccess文件可以的事情,主要包括:文件夹密码保护、用户自定义重定向、自定义404页面、扩展名伪静态化、禁止特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,等等。
修改这个配置: AllowOverride None(修改为AllowOverride All)
要注意一点那就是必须打开此目录的FollowSymLinks 符号链接属性,且在.htaccess里要声明RewriteEngine on
一些我们需要注意的地方:
FollowSymlinks必须启用,这是rewrite引擎的安全需求。
通常FollowSymlinks在Apache的主配置文件中就已经启用了,所以通常可以省略。
RewriteEngine命令用于启用rewrite引擎
IfModule命令用于判断Apache是否安装了mod_rewrite模块
mod_rewrite会处理所有提交给Apache的URL请求,并与之后的规则进行匹配
基本正则表达式:
因为URL重定向语法中大量使用了perl的正则表达式,并且正则是每隔一段时间不用都必然会淡忘的东西,所以我们有必要先回顾一下基本的正则写法:
. 匹配一个字符,(范围是换行符以外的所有字符)
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 字符串以……开始
$ 字符串以……结束
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
() $1 $2 一个括号代表一个分组,第一个括号里匹配的内容就用$1引用,第二个括号匹配的内容用$2引用,以此类推......
指令讲解:
1.重写规则的指令:
对于Rewrite来说共有九个指令:
RewriteBase,
RewriteCond,
RewriteEngine,
RewriteLock,
RewriteLog,
RewriteLogLevel,
RewriteMap,
RewriteOptions,
RewriteRule。
通常最常用的是 RewriteEngine, RewriteBase, RewriteCond, RewriteRule 四个指令,
下面简单介绍这四个指令。
RewriteEngine: 就是是否使用 Rewrite 模式的开关, 使用就设置成 on, 否则设置成 off。
RewriteBase:设置了目录级重写的基准URL,RewriteBase 的作用域为: directory, .htaccess
多数网站URL不是直接对应于其物理文件路径的,在这种情况下,
就必须用RewriteBase指令来指定正确的URL前缀。
通常默认的虚拟主机的网站在使用.htaccess 进行重写规则时不需要执行设置该指令.
因为 RewriteBase 默认值是该 .htaccess 文件所在的目录地址.
但是如果使用目录别名的话就需要设置这个指令了,例如 alias
举个例子,如果将1.html 重定向为1.php 设置为 RewriteBase /base/,
那么将会重定向到http://yourdomain.com/base/1.php。
对于重写基准目录,我们还可以通过将$1.php变成/$1.php实现直接变换,这时就可以将RewriteBase省略。
如果重定向到新的主机地址(域名),RewriteBase也就没有出现的必要了。
RewriteCond:指令定义一条规则条件。
在一条RewriteRule指令前面可能会有一条或多条RewriteCond指令,
只有当自身的模板(pattern)匹配成功且这些条件也满足时规则才被应用于当前URL处理。
注意,RewriteCond 指令后面可带 Flag, 现在只要2个可用,
一个是 NC(不区分大小写的意思), 一个是 OR(连接下一个条件)。
RewriteRule:是一个简单的命令告诉mod_rewrite这个模块如何去重写,
关键的地方在于可以在模式和替换中使用正则表达式来匹配相应的字符,
正则表达式的广泛的灵活性能将动态的URL转换成各式各样的符合要求的静态URL
格式: RewriteRule Pattern Substitution [flags]
在URL重写的匹配部分中, 服务器会把请求的URL的一部分删除掉,再传递给Pattern部分进行匹配.
重写结束后再添加上去.
所有平常我们看到的匹配规则总是不带网址前面的那些域名的什么东西的. 也不带什么目录什么的.
这些 apache已经给删掉了. 处理完后再加到前面。
但是有个例外就是如果 Substitution 部分是带 http:// 开头的话, 那就直接重定向了. 服务器不会把先前删除的再给加上了. 不然就出错了。
Apache Rewrite规则修正符 :
R 强制外部重定向 redirect|R [=code] (强制重定向 redirect)
例如: [R=301,L] 永久重定向; [R=302,L] 临时重定向;R默认为302
F 禁用URL,返回403HTTP状态码。
G 强制URL为GONE,返回410HTTP状态码。
P 强制使用代理转发。
L 表明当前规则是最后一条规则,停止分析以后规则的重写。
N 重新从第一条规则开始运行重写过程。
C 与下一条规则关联
2.服务器变量
NAME_OF_VARIABLE 具体数值见下表:
HTTP_USER_AGENT //主要用于检测访问者系统和浏览器等
HTTP_REFERER //从哪个页面链接过来
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST //取请求的域名 例如:www.test.com;不包括“http://”和“ /”
REQUEST_URI //这是在HTTP请求行中所请求的资源。例如:/share77.html
相对地址,就是相对根目录的地址,就是域名/后面的成分,格式上包括最前面的“/”
REQUEST_FILENAME //这是与请求相匹配的完整的本地文件系统的文件路径名或描述.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
这两句语句的意思是请求的文件或路径是不存在的,
如果文件或路径存在将返回已经存在的文件或路径
HTTP_PROXY_CONNECTION
HTTP_ACCEPT
REMOTE_ADDR
REMOTE_HOST
REMOTE_USER
REMOTE_IDENT
REQUEST_METHOD
SCRIPT_FILENAME
PATH_INFO
QUERY_STRING
AUTH_TYPE
DOCUMENT_ROOT
SERVER_ADMIN
SERVER_NAME
SERVER_ADDR
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME
API_VERSION //这是正在使用的httpd中(服务器和模块之间内部接口)的Apache模块API的版本,
其定义位于include/ap_mmn.h中。此模块版本对应于正在使用的Apache的版本
(比如,在Apache 1.3.14的发行版中,这个值是19990320:10)。
通常,对它感兴趣的是模块的作者。
THE_REQUEST //这是由浏览器发送给服务器的完整的HTTP请求行。
(比如, “GET /index.html HTTP/1.1″). 它不包含任何浏览器发送的附加头信息。
IS_SUBREQ //如果正在处理的请求是一个子请求,它包含字符串”true”,否则就是”false”。
模块为了解析URI中的附加文件,有可能会产生子请求。
实例分析:
1.重写,只对域名后的资源进行修改
RewriteRule ^/$ /about/ [R]
http://www.xxx.cn/index.html -> http://www.xxx.cn/index.php
RewriteRule index.html index.php
http://www.xxx.cn/test8.html -> http://www.xxx.cn/test.php?id=8 (这个也叫伪静态)
RewriteRule ^test([0-9]*).html$ test.php?id=$1
http://www.xxx.cn/cat-1-3.html -> http://www.xxx.cn/cat.php?id1=1&id2=3
RewriteRule ^cat-([0-9]+)-([0-9]+)\.html$ cat.php?id1=$1&id2=$2
前面第一个()中匹配的内容后面就用$1引用,第二个()中匹配的就用$2应用……
将.htm页面映射到.php:
RewriteRule ^(.*)\.htm$ $1.php [NC]
注意事项:
该RewriteRule能够将.htm静态页面映射到.php动态页面
如果通过.htm进入,浏览器地址栏显示的是.htm扩展名,但服务器上实际执行的是.php
[NC]表示“不区分大小写”
增加一个R标识符,重写即变为重定向:
RewriteRule ^(.*)\.htm$ $1.php [R,NC,L]
注意事项:
该RewriteRule能够将.htm静态页面重定向到.php动态页面
如果通过.htm进入,浏览器地址栏会自动转为.php,这也是重定向的本质
当访问163.com时 跳转到www.163.com
RewriteCond %{HTTP_HOST} ^163.com [NC]
RewriteRule ^(.*) http://www.163.com$1 [R=301,L]
当访问这个 70.40.213.183 开头的 ip时,跳转到www.163.com域名
RewriteCond %{HTTP_HOST} ^70.40.213.183 [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^(.*) http://www.163.com/ [L]
#声明Client请求的主机中前缀是70.40.213.183, [NC] 的意思是忽略大小写