日常工作中使用301重定向的情况很多:如网页目录结构变动,网页重命名、网页的扩展名改变、网站域名改变、SEO优化、等等,301重定向可以很方便的使页面实现跳转。

参考 URL重写模块

一、首先更改配置文件

[root@slave logs]# cat ../conf/vhosts/test.com.conf               #test.com.conf 配置文件
server    
{
        listen       80;
        server_name  test.com www.test.com;                       #服务器的基本名称,多域名用空格隔开
        root   /data/web;                                       
        access_log  logs/test.com.access.log;                    
        
        if ($host != 'www.test.com')                                         #if指令 用于条件判断
        {
        rewrite ^/(.*) http://www.test.com/$1 permanent;          #注意这里 访问test.com 301重定向到 www.test.com
        }
 
        #rewrite ^/bbs/(.*) http://bbs.test.com/$1 permanent;      #此处注释将在下面使用

location / 
        {
            index  index.html index.htm index.php;
        }

error_page 500 502 503 504 /50x.html;
        location =/50x.html
        {
            root html;
        }

location ~* \.php$
        {
            root /data/web;
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME  /data/web$fastcgi_script_name;
            include       fastcgi_params;
        }
}

二、重定向涉及到指令 

1 rewrite 指令
(rewrite指令 正则表达式 代替的URI flag标记 )
语法:rewrite regex replacement flag
默认值:none
使用字段:server, location, if
按照相关的正则表达式或者字符串来重写URI,rewrite指令按照在配置文件中出现的顺序执行;可以在重写指令后面添加标记。
注意:如果替换的字符串以http://开头,请求将被301或者302 URL重定向,并且不再执行多余的rewrite指令。

注意:重写表达式只对相对路径有效,如果你想配对主机名(比如 www.test.com),请与 if 指令配合使用 例如上边的配置文件中的301重定向。

尾部的标记(flag)可以是以下的值:

last - 完成重写指令,之后搜索相应的URI或location。

break - 完成重写指令,之后停止搜索。

redirect - 返回302临时重定向,浏览器地址栏会显示跳转后URL地址。

permanent - 返回301永久重定向。浏览器地址栏会显示跳转后URL地址。

引用张宴老师书上一段

在以上的标记中!

last 与 break 用来实现URI重写,浏览器地址栏URL地址不变,但是在服务器端访问的路径已经发生了变化。

redirect 与 permanent 用来实现URL跳转,浏览器地址栏会显示跳转后URL地址。

上边总结很重要,不同的环境下的rewrite 需使用不同 flag标记。

last 与 break 是有区别的!

一句话 last标记 在匹配后继续搜索,而break 标记在匹配后则停止搜索。

因此,一般在根location中 (即 location /{..}),或者直接写在server 标签中的rewrite 规则请使用last标记,而在非根location中 (比如 location /bbs/{..})请使用break标记。

2 if 指令
(if指令 (条件) {一些指令})
语法:if (condition) { … }
默认值:none
使用字段:server, location
判断一个条件,如果条件成立,则后面的大括号内的指令将执行,相关配置从上级继承。
条件可以是下边的任意一个:

2.1  变量名称;不成立的值为:" "(空字符串)“或者一些用“0”开始的字符串。

2.2  变量比较可以使用= (表示等于)或者!= (表示不等于)运算符。

2.3  正则表达式的模式匹配使用符号 ~*或~:

~为区分大小写的匹配。

~*不区分大小写的匹配(firefox匹配FireFox)。

!~和!~*意为“不匹配的”。

2.4  测试目标 -f/-d/-e/-x

使用-f和!-f检查一个文件是否存在。

使用-d和!-d检查一个目录是否存在。

使用-e和!-e检查一个文件,目录或者软链接是否存在。

使用-x和!-x检查一个文件是否为可执行文件。

正则表达式的一部分可以用圆括号括起来,方便之后按照顺序用$1-$9来引用。
#比如 rewrite ^/(.*) http://www.test.com/$1 permanent;

3 set 指令

语法:set variable value 
默认值:none
使用字段:server, location, if 
指令设置一个变量并为其赋值,其值可以是文本,变量和它们的组合。
你可以使用set定义一个新的变量,但是不能使用set设置$http_xxx头部变量的值

综合上面的三个指令,再次修改 test.com.conf 配置文档,完成301跳转。

server_name  test.com www.test.com; #此处未更改

if ($host ~* ^(.*?)\.test\.com$){         #注意此处if判断和上边if判断不同 
        set $var_domain '1';                          #给变量赋值,值使用单引号扩起来
        }

if ($var_domain !~ '1'){                      #变量不匹配'1' 则执行 rewrite 
        rewrite ^/(.*) http://www.test.com/$1 permanent; #301
        }                                                          #变量不匹配,说明 请求头的host 不是www.test.com

#比如 curl -ILv test.com

> Host: test.com
> Accept: */*
>

三、全局变量
#在if location rewrite 指令中可以使用以下全局变量。

$args #这个变量等于请求行中的参数。
$content_length #请求头中的Content-length字段。
$content_type #请求头中的Content-Type字段。
$document_root #当前请求在root指令中指定的值。
$host #请求主机头字段,否则为服务器名称。
$http_user_agent #客户端agent信息
$http_cookie #客户端cookie信息
$limit_rate #这个变量可以限制连接速率。
$request_body_file #客户端请求主体信息的临时文件名。
$request_method #客户端请求的动作,通常为GET或POST。
$remote_addr #客户端的IP地址。
$remote_port #客户端的端口。
$remote_user #已经经过Auth Basic Module验证的用户名。
$request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。
$query_string #与$args相同。
$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相同。

四、测试301重定向
#使用curl命令跟踪URL跳转!
#注意 > "表示客户端发送的信息"; < "表示服务器返回的信息"!

# curl -A "Opera/9.80 (X11; Linux x86_64; U; zh-cn) Presto/2.9.168 Version/11.50" -ILv test.com
* About to connect() to test.com port 80 (#0)
*   Trying 192.168.56.20... connected
* Connected to test.com (192.168.56.20) port 80 (#0)
> HEAD / HTTP/1.1                               #请求方法为HEAD(与GET请求相一致的响应,只不过响应体将不会被返回) 
> User-Agent: Opera/9.80 (X11; Linux x86_64; U; zh-cn) Presto/2.9.168 Version/11.50  #浏览器类型
> Host: test.com                                #初始URL中的主机和端口(在HTTP/1.1协议中,所有的请求头,除Host外,都是可选的)
> Accept: */*                                   #浏览器可接受的MIME类型
>                                               #发送空行
< HTTP/1.1 301 Moved Permanently                #服务器返回301状态,test.com 被重定向了
HTTP/1.1 301 Moved Permanently
< Server: nginx/1.0.5                           #Server 表示服务器名字
Server: nginx/1.0.5
< Date: Wed, 10 Aug 2011 01:46:42 GMT
Date: Wed, 10 Aug 2011 01:46:42 GMT
< Content-Type: text/html                       #Content-Type 表示后面的文档属于什么MIME类型
Content-Type: text/html
< Content-Length: 184                           #Content-Length 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据
Content-Length: 184
< Connection: keep-alive                        #Connection 表示是否需要持久连接如果看到这里的值为“Keep-Alive”则是
Connection: keep-alive
< Location: http://www.test.com/                #Location 表示客户应当到哪里去提取文档,现在转跳到www.test.com
Location: http://www.test.com/

<                                               #返回空行
* Connection #0 to host test.com left intact        #重复
* Issue another request to this URL: 'http://www.test.com/'
* About to connect() to www.test.com port 80 (#1)
*   Trying 192.168.56.20... connected
* Connected to www.test.com (192.168.56.20) port 80 (#1)
> HEAD / HTTP/1.1
> User-Agent: Opera/9.80 (X11; Linux x86_64; U; zh-cn) Presto/2.9.168 Version/11.50
> Host: www.test.com
> Accept: */*

< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.0.5
Server: nginx/1.0.5
< Date: Wed, 10 Aug 2011 01:46:42 GMT
Date: Wed, 10 Aug 2011 01:46:42 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 151
Content-Length: 151
< Last-Modified: Sat, 30 Jul 2011 07:36:02 GMT
Last-Modified: Sat, 30 Jul 2011 07:36:02 GMT
< Connection: keep-alive
Connection: keep-alive
< Accept-Ranges: bytes
Accept-Ranges: bytes


* Connection #1 to host www.test.com left intact
* Closing connection #0
* Closing connection #1

查看日志
#注意日志中的http状态码“200|301|404”,后面的那个数字表示文件内容长度!!
#日志记录了两次,第一次状态301,第二次状态200.

[root@slave ~]# tail /usr/local/nginx/logs/test.com.access.log -n2
192.168.56.1 - - [10/Aug/2011:09:46:42 +0800] "HEAD / HTTP/1.1" 301 0 "-" "Opera/9.80 (X11; Linux x86_64; U; zh-cn) Presto/2.9.168 Version/11.50"
192.168.56.1 - - [10/Aug/2011:09:46:42 +0800] "HEAD / HTTP/1.1" 200 0 "-" "Opera/9.80 (X11; Linux x86_64; U; zh-cn) Presto/2.9.168 Version/11.50"

日志分析 
192.168.56.1 是来访IP;[10/Aug/2011:09:46:42 +0800] 前面是时间,0800是时区;“GET 是服务器的动作,GET是从服务器上获取内容 /;HTTP/1.1″ 使用HTML1.1协议获,301,200 是返回状态码,前者表示301永久重定向,后者表示200成功获取;151 是文件内容长度; "-" 在此处代表访问的url,这里为空; "Opera/9.80 (X11; Linux x86_64; U; zh-cn) Presto/2.9.168 Version/11.50" 表示的是使用的是 Linux 操作系统,Opera浏览器,第几版本。

五 额外的http协议与http状态码

1 超文本传输协议(HTTP,HyperText Transfer Protocol)
http://zh.wikipedia.org/wiki/HTTP
通常,由HTTP客户端发起一个请求,创建一个到服务器指定端口(默认是80端口)的TCP连接;HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器向客户端发回一个状态行,比如"HTTP/1.1 200 OK",和响应的消息,消息的消息体可能是请求的文件、错误消息、或者其它一些信息。
通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。

2 HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。
http://zh.wikipedia.org/wiki/HTTP状态码
状态代码的第一个数字代表当前响应的类型:
1xx消息——请求已被服务器接收,继续处理
2xx成功——请求已成功被服务器接收、理解、并接受
3xx重定向——需要后续操作才能完成这一请求
4xx请求错误——请求含有词法错误或者无法被执行
5xx服务器错误——服务器在处理某个正确请求时发生错误

3 HTTP请求头概述 (HttpServletRequest) HTTP客户程序(例如浏览器),向服务器发送请求的时候必须指明请求类型(一般是GET或者POST或者HEAD)例如上面的curl (-I)测试使用了HEAD方法!
http://baike.baidu.com/view/2532173.html?tp=1_01
如有必要,客户程序还可以选择发送其他的请求头。大多数请求头并不是必需的,但Content-Length除外。对于POST请求来说Content-Length必须出现。 下面是一些最常见的请HTTP请求头概述

六 一些简单 rewrite 例子

#1 域名重定向 test.com 301 转跳到 www.test.com

if ($host ~* ^www\.test\.com$)
}
set $var_domain '1';            
}

if ($var_domain !~ '1')
{
rewrite ^/(.*)$ http://www.test.com/$1 permanent;     
}

#还有更简单的方法,上边为了练习set指令(可以给变量赋值哦)!

if ($host != 'www.test.com')
{
rewrite ^/(.*)$ http://www.test.com/$1 permanent;
}

#2 /bbs目录 301 转跳到 bbs.test.com

location =/bbs/
{
rewrite ^/bbs/(.*) http://bbs.test.com/$1 permanent;
}

#3 将多级目录下的文件转换成一个文件

rewrite "^/(\w{3})[-]?(\w{4})[-]?(\w{4})[-]?(\w{5})$" /$1/$2/$3/$4.php last;

rewrite "^/(\d{4})[-]?(\d{2})[-]?(\d{2})[-]?(\d{2})$"  /$1/$2/$3/$4.php last;

请求的URL

http://www.test.com/abcabc2abc3index

http://www.test.com/2011081701

多级目录

[root@slave web]# ls abc/abc2/abc3/index.php

[root@slave web]# ls 2011/08/17/01.php

nginx-301重定向开始的更多相关文章

  1. Nginx 301重定向的配置

    301重定向是很常见的需求,比如访问 fz1688.com,自动跳到 www.fz1688.com.或者倒过来,访问 www.fz1688.com 跳到 fz1688.com.Nginx 中配置 30 ...

  2. Nginx 301重定向域名

    为何要使用301重定向 在网站建设中需要网页重定向的情况很多:如网页目录结构变动,网页重命名.网页的扩展名改变.网站域名改变等.如果不做重定向,用户的收藏和搜索引擎数据库中的旧地址只能让访客得到一个4 ...

  3. nginx 301 重定向设置不含www到www域名

    如果需要将不含www主机的域名301重定向到含www的域名,如将 shwww.net 重定向至 www.shwww.net,nginx 配置指令如下: server { server_name shw ...

  4. nginx 301重定向一种实现方法

    假设要使用的域名是b.com,以前的老域名是a.com,则以下设置让nginx把a.com的请求访问转发到b.com,并返回301给浏览器. server { listen 80; server_na ...

  5. Nginx 301重定向设置

    server { server_name www.***.com ***.com; if ($host != 'www.***.com' ) { rewrite ^/(.*)$ http://www. ...

  6. nginx配置301重定向

    1. 简介 301重定向可以传递权重,相比其他重定向,只有301是最正式的,不会被搜索引擎判断为作弊 2. 栗子 savokiss.com 301到 savokiss.me 3. nginx默认配置方 ...

  7. NGINX -- 详解Nginx几种常见实现301重定向方法上的区别

    Nginx下常见的301跳转有以下三种,虽然都能达到同样的目的.但是三种写法上还是有区别的,主要的区别是在正则匹配的性能上. 第一种:使用rewrite指令,通过正则匹配所有的URI后再去掉开头第一个 ...

  8. [转] linux学习第四十四篇:Nginx安装,Nginx默认虚拟主机,Nginx域名重定向

    Nginx安装 进入存放源码包的目录: cd /usr/local/src 下载源码包: wget http://nginx.org/download/nginx-1.12.1.tar.gz 解压: ...

  9. nginx 301 302跳转配置总结

    首先看简单的代码示例,关于nginx 301 302跳转的. 301跳转设置: server { listen 80; server_name 123.com; rewrite ^/(.*) http ...

  10. Nginx 301与302配置

    说明 1.首先看一个完整代码示例,关于nginx 301 302跳转的. 301跳转设置: server { listen 80; server_name 123.com; rewrite ^/(.* ...

随机推荐

  1. COJ 0200 Fibonacci

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=200 试题描述: 地球人都知道Fibonicca数列: 1 1 2 3 5 ...

  2. 安装loadrunner11 ,出现如下错误如何解决?

    出现的问题是: 安装LoadRunner 11时弹窗提示"Micosoft Visual C++ 2005 SP1 可再发行组件包(X86):'命令行选项语法错误.键入命令 / ? 可获得帮 ...

  3. cf701C They Are Everywhere

    Sergei B., the young coach of Pokemons, has found the big house which consists of n flats ordered in ...

  4. Cgroup - Linux 内存资源管理

    Hi ,我是 Zorro .这是我的微博地址,我会不定期在这里更新文章,如果你有兴趣,可以来关注我呦. 另外,我的其他联系方式: Email: mini.jerry@gmail.com QQ: 300 ...

  5. 【mac开发.NET】No installed provisioning profiles match the installed iOS signing identities

    编译错误提示 /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets: Er ...

  6. HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)

    题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...

  7. UVa 340 Master-Mind Hints (优化查找&复制数组)

    340 - Master-Mind Hints Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_on ...

  8. Jquery UI的datepicker插件使用

    原文链接;http://www.ido321.com/375.html Jquery UI是一个非常丰富的Jquery插件,而且UI的各部分插件能够独自分离出来使用.这是其它非常多Jquery插件没有 ...

  9. 安装android studio 出现的路径问题 tools.jar' seems to be not in Android Studio classpath

    尝试一下android studio  ,谁知出现路径问题 'tools.jar' seems to be not in Android Studio classpath. Please ensure ...

  10. hdu 1205

    #include <stdio.h> int a[1005000]; int main() { int t; scanf("%d",&t); while(t-- ...