重定向 重写

什么是URL重定向:
  URL重定向(URL redirection,或称网址重定向或网域名称转址),是指当使用者浏览某个网址时,将他导向到另外一个网址的技术。
php


重写和重定向的区别:html

重定向 :浏览器知道页面位置发生变化,从而改变地址栏显示的地址
              搜索引擎意识到页面被移动了,从而更新搜索引擎索引,将原来失效的连接从搜索结果中移除
               临时重定向(R=302)和永久重定向(R=301)都是亲搜索引擎的,是SEO的重要技术
web


重写:用于将页面映射到本站另外一页面,若重写到另外一网络主机(域名),则按重定向处理
正则表达式



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引用,以此类推......
apache


指令讲解:
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,这也是重定向的本质



2..基于域名的重定向
 当访问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] 的意思是忽略大小写 
#声明Client请求的主机中前缀不为空 
#[L]意味着当即中止重写操做,并再也不应用其余重写规则。
。 
 



又跨域,又要url不变的重定向

咱们能够用如下方法解决:(这样浏览器中的url没有变化 , 可是内容已是sina的了)

RewriteRule /66.htm$  http://www.sina.com.cn [P]

RewriteRule /66.htm$  http://127.0.0.1:8080/sohu/sd.jsp [P]

注意:这里的P是代理模式转发,必须用url全称,而且要保证modProxy打开,也就是下面httpd.conf中的着两句:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

若是不打开则会出现403禁止页面。


 
 


一、图片重定向
RewriteEngine On
RewriteCond %{HTTP_HOST} ^localhost$    //若是域名是localhost
RewriteCond %{REQUEST_FILENAME} !-f     //而且访问的文件找不到
RewriteRule ^images/(.+) http://127.0.0.1/test/showimages/$1 [R=302,L]     
//则跳转到另外一个域名下的另外一个目录访问这个图片


当请求不存在的资源时, 统必定义到根目录下的 404.html
文件名不存在、目录不存在、跳转404页面
RewriteCond %{REQUEST_FILENAME} !-f      
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /404.html [L]
 
限制访问. 好比来自一些不友好的网站链接过来的请求. 不容许访问.
下例中若是 HTTP_REFERER 中包含 sex 字符, 则不容许访问.
RewriteCond %{HTTP_REFERER} sex
RewriteRule ^.*$ - [F]
 
伪静态化, 好比访问 /user20.html 则调用viewUser.php 显示用户ID为20的用户资料
RewriteRule ^user([0-9]*)\.html$ viewUser.php?userid=$1
 
喜欢用二级域名的比较实用了. 好比网站目录下有 user, upload 等几个目录,
能够经过 http://www.test.com/user 这样的模式访问.
可是若是想作成统一用二级域名模式访问: http://user.test.com , 可是不容许 http://www.test.com/user 这样访问.
那么就像下面这样来限制.
RewriteCond %{REQUEST_URI} ^/user
RewriteRule ^.*$ http://user.test.net" [L]
 
防止图片盗链
RewriteEngine On
RewiteBase /
RewriteCond %{HTTP_REFERER} !^http://(.+.)?baidu.com/ [NC]        //若是来源网址不是*.baidu.com
RewriteCond %{HTTP_REFERER} !^$                                   //而且来源网址不是空

RewriteRule .*.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]     //若是访问的文件后缀是jpeg,jpg,gif,bmp,png的图片,则重定向到一个固定的图片


 

咱们使用 .htaccess 来定义重写规则假设域名为: www.test.com

.htaccess 放在网站根目录下好比: /.htaccess

例子1: 全部请求都定向到 index.php 脚本注意要排除 index.php 自己好比就进入死循环了.

RewriteRule !^index\.php$ index.php [L]

例子2按照时间显示不一样的页面好比访问 hello.html 页面时
若是 在 8:00-19:00 的时候访问显示 hello.day.html 其余时间访问显示: hello.night.html

RewriteCond %{TIME_HOUR}%{TIME_MIN} >0700

RewriteCond %{TIME_HOUR}%{TIME_MIN} <1900

RewriteRule ^hello\.html$ hello.day.html

RewriteRule ^hello\.html$ hello.night.html

 




 

官方的例子重写规则写在 httpd.conf 文件里请求地址为: http://www.test.com/somepath/pathinfo, 
看下面几种结果.   
Given Rule => Resulting Substitution

-------------------------------------------------------------------------------

^/somepath(.*) otherpath$1 => 不支持无效的重写语句

^/somepath(.*) otherpath$1 [R] => 不支持无效的重写语句

^/somepath(.*) otherpath$1 [P] => 不支持无效的重写语句

-------------------------------------------------------------------------------

^/somepath(.*) /otherpath$1 => /otherpath/pathinfo

^/somepath(.*) /otherpath$1 [R] =>  http://www.test.com/otherpath/pathinfo  外部重定向

^/somepath(.*) /otherpath$1 [P] =>  不支持很傻.

-------------------------------------------------------------------------------

^/somepath(.*) http://www.test.com/otherpath$1 => /otherpath/pathinfo

^/somepath(.*) http://www.test.com/otherpath$1 [R] => http://www.test.com/otherpath/pathinfo  外部重定向

^/somepath(.*) http://www.test.com/otherpath$1 [P] => 不支持很傻.

----------------------------------------------  ----------------------------------

^/somepath(.*) http://www.xxx.com/otherpath$1 => http://www.xxx.com/otherpath/pathinfo  外部重定向

^/somepath(.*) http://www.xxx.com/otherpath$1 [R] => http://www.xxx.com/otherpath/pathinfo  外部重定向 [R] 多余.

^/somepath(.*) http://www.xxx.com/otherpath$1 [P] => http://www.xxx.com/otherpath/pathinfo 内部网关重定向



一样的请求上面的地址若是在 .htaccess 文件里的写法注意和 httpd.conf 写法的区别.

好比 .htaccess 文件在目录一个虚拟主机的根目录下
而后请求 http://www.test.com/localpath/pathinfo 看下面的几种结果.

Given Rule => Resulting Substitution

-------------------------------------------------------------------------------

^localpath(.*) otherpath$1=> /otherpath/pathinfo

^localpath(.*) otherpath$1  [R] =>  http://www.test.com/otherpath/pathinfo 外部重定向

^localpath(.*) otherpath$1  [P] => 不支持很傻.

-------------------------------------------------------------------------------

^localpath(.*) /otherpath$1 => /otherpath/pathinfo 注意 /otherpath$1 和 otherpath$1 的区别

^localpath(.*) /otherpath$1 [R] => http://www.test.com/otherpath/pathinfo 外部重定向

^localpath(.*) /otherpath$1 [P] => 不支持很傻.

-------------------------------------------------------------------------------

^localpath(.*) http://www.test.com/otherpath$1      /otherpath/pathinfo

^localpath(.*) http://www.test.com/otherpath$1 [R]  http://www.test.com/otherpath/pathinfo 外部重定向

^localpath(.*) http://thishost/otherpath$1 [P] => 不支持很傻.

-------------------------------------------------------------------------------

^localpath(.*) http://www.test.com/otherpath$1 => http://www.test.com/otherpath/pathinfo 外部重定向

^localpath(.*) http://www.xxx.com/otherpath$1 [R] => http://www.xxx.com/otherpath/pathinfo 外部重定向 [R] 可省略

^localpath(.*) http://www.xxx.com/otherpath$1 [P] => http://www.xxx.com/otherpath/pathinfo 内部网关重定向






Apache重写规则的常见应用(rewrite)

      
 一:目的

  本文旨在提供怎么用Apache重写规则来解决一些常见的URL重写方法的问题,经过常见的

  实例给用户一些使用重写规则的基本方法和线索。

  
:为何须要用重写规则?

  一个网站,若是是长期须要放在internet上提供服务,一定会有不断地更新和维护,如临

  时转移到其余服务器进行维护,从新组织目录结构,变换URL甚至改动到新的域名等等,

  而为了让客户不会所以受到全部影响,最佳的方法就是使用Apache Rewrite Rule(重写

  规则)

  
重写规则的做用范围

  1) 能使用在Apache主设置文件httpd.conf

  2) 能使用在httpd.conf里定义的虚拟主机设置中

  3) 能使用在基本目录的跨越设置文件.htaccess

  
:重写规则的应用条件

  只有当用户的WEB请求最终被导向到某台WEB服务器的Apache后台,则这台WEB服务器接受

  进来的请求,根据设置文件该请求是主设置仍是虚拟主机,再根据用户在浏览器中请求的

  URI来配对重写规则而且根据实际的请求路径配对.htaccess中的重写规则。最后把请求

  的内容传回给用户,该响应可能有两种: 

1) 对浏览器请求内容的外部重定向(Redirect)到另外一个URL

  让浏览器再次以新的URI发出请求(R=301R=302,临时的或是永久的重定向)

  如:一个网站有正规的URL和别名URL,对别名URL进行重定向到正规URL,或网站改换

  成了新的域名

  则把旧的域名重定向到新的域名(Redirect) 

2) 也多是由Apache内部子请求代理产生新的内容送回给客户[P,L]

  这是Apache内部根据重写后的URI内部经过代理模块请求内容并送回内容给客户,而客户

  端浏览器并不知道,浏览器中的URI不会被重写。但实际内容被Apache根据重写规则后的URI获得。

  如:在公司防火墙上运行的Apache启动这种代理重写规则,代理对内部网段上的WEB服务

  器的请求。

  
:重写规则怎样工做?

  咱们假定在编译Apache时已把mod_rewrite编译成模块,确信你的httpd.conf中有

  LoadModule rewrite_module libexec/mod_rewrite.so

  而且在Addmodule中有  Addmodule mod_rewrite.c则能使用重写规则。


  当外部请求来到ApacheApache调用重写规则中的定义来重写由用户浏览器指定请求的

  URI,最后被重写的URI若是是重定向,则送由浏览器做再一次请求;若是是代理则把重写

  后的URI交给代理模块请求最终的内容(Content),最后把内容送回给浏览器。

  
什么时候使用.htaccess中的重写规则定义?

  若是你对你的的网站内容所在的服务器没有管理员权限,或你的网站放在ISP的服务器

  上托管等等条件下,你没法改写主设置文件,然而你能对你的WEB站点内容所在的目录

  有写权限,则你能设置本身的.htaccess

  文件达到一样的目的。但你须要肯定主设置文件中对你的网站所在的目录定义了下面的内

  容:

  Options Indexes FollowSymLinks

  AllowOverride all

  不然你的.htaccess不会工做。

  
应用举例

  假定Apache被编译安装在主机192.168.1.56/usr/local/apache/ 目录下面,咱们编

  译进了重写和代理模块。  

1) 隐藏Apache下的某个目录,使得对该目录的全部请求都重定向到另外一个文件。

  a> httpd.conf的实现方法

  咱们放下面的部分到/usr/local/apache/conf/httpd.conf

  options Indexes followsymlinks

  allowoverride all

  rewriteengine on

  rewritebase /

  rewriterule ^(.*)$ index.html.en [R=301]

  注:rewriteengine on 为重写引擎开关,若是设为off,则全部重写规则定义将不被应

  用,该开关的另外一好处就是若是为了临时拿掉重写规则,则改成off再重启动Apache

  可,没必要将下面一条条的重写规则注释掉。

  rewritebase / 的做用是若是在下面的rewriterule定义中被重写后的部分(此处为文件

  名index.html.en)前面没有/,则是相对目录,相对于这个rewritebase后面的定义也就

  是/usr/local/apache/htdocs/index.html.en,不然,若是此处没有rewritebase /

  一项,则被重写成

  http://192.168.1.56/usr/local/apache/htdocs/manual/index.html.en ,显然是

  不正确的。

  不过这里咱们也能不用rewritebase / , 而改成

  rewriteengine on

  rewriterule ^(.*)$ /index.html.en [R=301]

  或

  rewriteengine on

  rewriterule ^(.*)$ http://192.168.1.56/index.html.en [R=301]

  

       b> .htaccess的实现方法

  咱们先放下面的部分到httpd.conf

  options Indexes followsymlinks

  allowoverride all

  而后放下面的部分到/usr/local/apache/htdocs/manual/.htaccess

  rewriteengine on

  rewritebase /

  rewriterule ^(.*)$ index.html.en [R=301]

  注:对文件.htaccess所做的全部改动没必要重启动Apache.

  问:要是把这个manual目录重定向到用户jephe的本身的主目录呢?

  用下面的.htaccess方案。

  rewriteengine on

  rewritebase /~jephe/

  rewriterule ^(.*)$ $1 [R=301]

  则对manual目录下全部文件的请求被重定向到~jephe目录下相同文件的请求。

  
2) 转换www.username.domain.com的对于username的主页请求为

  www.domain.com/username

  对于HTTP/1.1的请求包括一个Host: HTTP头,咱们能用下面的规则集重写

  http://www.username.domain.com/anypath 到 /home/username/anypath

  Rewriteengine on

  rewritecond %{HTTP_HOST} ^www.[^.]+.host.com$

  rewriterule ^(.+) %{HTTP_HOST}$1 [C]

  rewriterule ^www.([^.]+).host.com(.*) /home/$1$2

  注:

  rewritecond 条件重写规则,当知足后面定义的条件后才会应用下面的重写规则,

  rewritecond有各类变量

  ,请查阅相关文件。

  
3) 防火墙上的重写规则代理内部网段上服务器的请求。

  NameVirtualhost 1.2.3.4

  servername www.domain.com

  rewriteengine on

  proxyrequest on

  rewriterule ^/(.*)$ http://192.168.1.3/$1 [P,L]

  注:当外部浏览器请求www.domain.com时被解析到IP地址1.2.3.4 ,Apache 交出

  mod_rewrite处理转换成

  http://192.168.1.3/$1后再交由代理模块mod_proxy获得内容后传送回用户的浏览器。

  
4) 基本预先设定的转换MAP表进行重写 rewritemap

  转换www.domain.com/{countrycode}/anypath Map表中规定的URI,上面是虚拟主机

  中的定义

  rewritelog /usr/local/apache/logs/rewrite.log

  rewriteloglevel 9

  rewriteengine on

  proxyrequest on

  rewritemap sitemap txt:/usr/local/apache/conf/rewrite.map

  rewriterule ^/([^/]+)+/(.*)$ http://%{REMOTE_HOST}::$1 [C]

  rewriterule (.*)::([a-z]+)$ ${sitemap:$2|http://h.i.j.k