nginx_笔记分享_4_从301重定向开始

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

日常工作中使用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

 

#4 有意思的中文URL

rewrite ^/首页$ /index.html last;

请求的URL

日志

192.168.6.80 - - [25/Aug/2011:08:59:15 +0800] "GET /%E9%A6%96%E9%A1%B5 HTTP/1.1" 200 151 "-" "Opera/9.80 (X11; Linux x86_64; U; zh-cn) Presto/2.9.168 Version/11.50"

 

#5 伪静态,有什么用?静态页面更容易被搜索引擎收录的

rewrite "^/(.*)-forum-(.*)$" /$1.php?$2 last;  #rewrite 规则,适用于phpwind8系列!

http://bbs.test.com/read.php?tid=5      #真实存在的动态php页面
http://bbs.test.com/read-forum-5.html    #rewrite后的伪静态(原本不存在)html页面

http://bbs.test.com/thread.php?fid=5         #同上
http://bbs.test.com/thread-forum-fid-5.html    #同上

#phpwind,帮助文档中的rewrite 规则,适用于apache,更改一下就可以用在nginx上了。 
RewriteRule ^(.*)-htm-(.*)$ $1.php?$2

#phpwind 伪静态介绍!


本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/636076

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
7月前
|
存储 缓存 负载均衡
Nginx入门笔记
Nginx入门笔记
217 0
|
缓存 运维 负载均衡
华为大佬秘密撰写的Nginx运维笔记遭人恶意开源,整整638页全泄露
众所周知,Nginx是当下最流行的Web服务器,它具有很强的负载均衡,反向代理,邮件代理以及静态缓存的功能。在提供这些功能的同时,Nginx的性能也极其优秀,可以轻松支持百万、千万级的并发连接,能够为Tomcat、Django等性能不佳的Web应用抗住绝大部分外部流量。那么,Nginx是如何实现高速并发处理呢? 今天小轩就在这里给大家介绍一份“Nginx”的实战笔记,整整638页。话不多说,直击主题。让我们一起来看看这份有着“百万点击播放量”的Nginx笔记吧。 由于篇幅受限,部分内容只能以截图的方式展示出来。需要完整版点击此处获取。 Nginx应用与运维实战 目录
|
1月前
|
应用服务中间件 nginx
Nginx:怎么携带参数重定向
通过合理配置Nginx的 `rewrite`指令和 `return`指令,可以实现携带参数的重定向。这不仅可以确保用户请求被正确重定向,还可以保留原始查询参数,满足更多复杂的重定向需求。
110 1
|
1月前
|
应用服务中间件 nginx
Nginx:怎么携带参数重定向
通过合理配置Nginx的 `rewrite`指令和 `return`指令,可以实现携带参数的重定向。这不仅可以确保用户请求被正确重定向,还可以保留原始查询参数,满足更多复杂的重定向需求。
67 2
|
2月前
|
网络协议 应用服务中间件 nginx
FFmpeg错误笔记(一):nginx-rtmp-module推流出现 Server error: Already publishing
这篇文章讨论了在使用nginx-rtmp-module进行RTMP推流时遇到的“Server error: Already publishing”错误,分析了错误原因,并提供了详细的解决办法,包括修改nginx配置文件和终止异常的TCP连接。
170 0
FFmpeg错误笔记(一):nginx-rtmp-module推流出现 Server error: Already publishing
|
6月前
|
Ubuntu 前端开发 JavaScript
技术笔记:Ubuntu:一个部署好的tomcat应用(war包)怎么用Nginx实现动静分离?
技术笔记:Ubuntu:一个部署好的tomcat应用(war包)怎么用Nginx实现动静分离?
|
3月前
|
JavaScript Java 应用服务中间件
|
4月前
|
安全 Ubuntu 搜索推荐
如何使用 Nginx 创建临时和永久重定向
如何使用 Nginx 创建临时和永久重定向
68 2
|
5月前
|
应用服务中间件 Linux nginx
FFmpeg开发笔记(四十)Nginx集成rtmp模块实现RTMP推拉流
《FFmpeg开发实战》书中介绍了如何使用FFmpeg向网络推流,简单流媒体服务器MediaMTX不适用于复杂业务。nginx-rtmp是Nginx的RTMP模块,提供基本流媒体服务。要在Linux上集成rtmp,需从官方下载nginx和nginx-rtmp-module源码,解压后在nginx目录配置并添加rtmp模块,编译安装。配置nginx.conf启用RTMP服务,监听1935端口。使用ffmpeg推流测试,如能通过VLC播放,表明nginx-rtmp运行正常。更多详情见书本。
132 0
FFmpeg开发笔记(四十)Nginx集成rtmp模块实现RTMP推拉流
|
4月前
|
Ubuntu 应用服务中间件 网络安全
如何使用 Apache 和 Nginx 创建临时和永久重定向
如何使用 Apache 和 Nginx 创建临时和永久重定向
89 0