04 . Nginx的Rewrite重写
Rewrite简介
# Rewrite对应URL Rewrite,即URL重写,就是把传入web的请求重定向到其他URL的过程.
# 当运维遇到要重写情况时,往往是要程序员把重写规则写好后,发给你,你再到生产环境下配置。对于重写规则
# 说到底就是正则匹配,做运维的岂能对正则表达式不了解的?最起码最基本的正则表达式会写。套用一句阿里的话(某网友说是阿里说的,不清楚到底是不是出自阿里)“不懂程序的运维,不是好运维;不懂运维的开发,不是好开发。”
# Nginx的重写模块rewrite是一个简单的正则表达式匹配与一个虚拟堆叠机结合,依赖于pcre库这也为我们之前安装的时候为什么需要安装pcre和pcre-devel软件的原因,rewrite会根据相关变量重定向和选择不同的配置,从一个 location跳转到另一个 location,不过这样的循环最多可以执行10次,超过后 nginx将返回500错误。同时,重写模块包含 set 指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。
功能及范围
# 功能:实现URL的重写,通过Rewrite规则,可以实现规范的URL,根据变量来做URL转向及选择配置。
# 作用范围:server{},location{},if{}
# 优先级:执行server块的rewrite指令 > 执行location匹配 >执行选定的location中的rewrite指令。
应用场景
# nginx的rewrite功能在企业中应用非常广泛:
# 1. 可以调整用户用户浏览的URL,看起来更加规范,合乎开发以及产品人员的需求。
# 2. 为了让搜索引擎收录网站内容及用户体验更好,企业将动态URL地址伪装成静态地址提供服务
# 3. 网站换新域名后,让旧的域名的访问跳转到信息的域名上
# 4. 根据特殊变量、目录、客户端的信息进行URL跳转等。
URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面的一种技术.
比如http://www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示为 http://www.123.com/news/123.html对于追求完美主义的网站设计师,就算是网页的地址也希望看起来尽量简洁明快。理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以,UrlRewrite可以让我们网站的网页更容易被搜索引擎所收录。
从安全角度上讲,如果URL中暴露太多的参数,无疑会造成一定量的信息泄露,可能会被一些黑客利用,对你的系统造成一定的损坏,所以静态化的URL地址可以给我们带来更高的安全性.
实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com,例如当用户访问flying.cn的80端口时,将其跳转到443端口.
Rewrite相关指令
Nginx Rewrite相关指令有重定向rewrite,if 语句,条件判断,全局变量,set,return
# if语句的应用环境和语法:
# 应用环境: server,location
if (condition) {
# 代表条件为真时的nginx操作,可以是反向代理,也可以是URL重写
}
if 可以支持如下条件判断匹配符号
~ # 正则匹配(区分大小写)
~* # 正则匹配(不区分大小写)
!~ # 正则不匹配(区分大小写)
!~* # 正则不匹配(不区分大小写)
-f和!-f # 用来判断是否存在文件
-d和!-d # 用来判断是否存在目录
-e和!-e # 用来判断是否存在文件或目录
-x和!-x # 用来判断文件是否可执行
Rewrite flag
rewrite: 指令根据表达式来重定向URI,或者修改字符串,可以应用于server,location,if环境下,每行rewrite指令最后跟一个跟一个flag标记,支持的flag标记有:
last: 相当于Apache里的[L]标记,表示终止继续在本location快中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用下一个location块进行处理,处理完成再从第一个location开始,循环五次报500错误.
break: 将此处重写的URI作为一个新的URI,在本块中继续进行处理,该标识将重写后的地址在当前location块中执行,不会将新的URI转向到其他location块.
redirect: 返回302临时重定向,浏览器地址会显示跳转后的URL地址.
permanent: 返回301永久重定向,浏览器地址会显示跳转后URL地址.
location / {
root /usr/share/nginx/html;
index index.html index.htm;
rewrite ^/.* http://www.taobao.com;
}
Rewrite匹配参考示例
Example1
# 有意思的域名跳转,39.108.140.0无论访问什么,最终都给跳转到www.taobao.com上**
vim /etc/nginx/conf.d/default.conf
location location / {
root /usr/share/nginx/html;
index index.html index.htm;
rewrite ^/.* http://www.taobao.com;
}
elinks --dump 39.108.140.0
*?[14]亲,请登录
*?? 消息 ?
*?[15]手机逛淘宝
Example2
# 访问http://39.108.140.0/abc/a/1.html ==> http://39.108.140.0/ccc/bbb/b.html
# 1./abc/a/1.html页面是否存在不重要
# 2./ccc/bbb/b.html页面必须存在
vim /etc/nginx/conf.d/default.conf
location /abc {
rewrite .* /ccc/bbb/b.html permanent;
}
nginx -s reload
elinks --dump 39.108.140.0/abc/a/1.html
b.html
# 这个abc目录是没有的,但是只要符合匹配条件就会跳转走
tail -2 /var/log/nginx/access.log
49.233.69.195[04/Nov/2019:12:22:19]"GET /abc/a/1.html HTTP/1.1" 301 169 "-"
49.233.69.195[04/Nov/2019:12:22:19]"GET /ccc/bbb/b.htmlHTTP/1.1" 200"http://39.108.140.0/abc/a/1.html"
# 无permanent,简单的rewrite请求一次
49.233.69.195 - - [04/Nov/2019:12:27:09 +0800] "GET /abc/a/1.html HTTP/1.1" 200 7 "-"
#有permanent,永久重定向301请求两次(成本高,容易看懂日志意思,友好)
Example3
# 访问http://39.108.140.0/2015/ccc/bbb/b.html ==> http://39.108.140.0/2014/ccc/bbb/b.html
mkdir /usr/share/nginx/html/2015/ccc/bbb/ -p
mkdir /usr/share/nginx/html/2014/ccc/bbb/ -p
echo 2014 > 2014/ccc/bbb/b.html
echo 2015 > 2015/ccc/bbb/b.html
vim /etc/nginx/conf.d/default.conf
location /2015 {
rewrite ^/2015/(.*)$ /2014/$1 permanent;
}
nginx -s reload
Example4
# 访问http://www.flying.com ==> http://cloud.com
# 因为是测试环境,注意客户端解析
mkdir /cloud
echo cloud > /cloud/index.html
vim /etc/nginx/conf.d/default.conf
location / {
root /cloud;
index index.html;
}
nginx -s reload
tail -2 /etc/hosts
39.108.140.0 cloud.com
39.108.140.0 flying.com
elinks --dump cloud.com
cloud
vim /etc/nginx/conf.d/default.conf
if ($host ~* flying.com){
rewrite .* http://cloud.com permanent;
}
elinks --dump flying.com
cloud
Example5
# 如果访问的.sh结尾的文件则返回403操作拒绝错误
return 指令用于返回状态码给客户端,应用于server,location,if环境
touch /usr/share/nginx/html/1.sh
vim /etc/nginx/conf.d/default.conf
location ~* \.sh$ {
return 403;
#return 301 http://www.baidu.com;
}
nginx -s reload
elinks --dump 39.108.140.0/index.html
123
elinks --dump 39.108.140.0/index.sh
403 Forbidden
Example6
# 不同浏览器访问不同结果(实现不同客户端(PC,安卓,IOS))访问不同的后端实例
if ($http_user_agent ~ Firefox) {
rewrite ^(.*)$ /firefox/$1 break;
}
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_user_agent ~ Chrome) {
rewrite ^(.*)$ /chrome/$1 break;
}
# 防止盗链
location ~*\.(gif|jpg|png|swf|flv)${
valid_referers none blocked www.cheng.com *.test.com;
if ($invalid_referer) {
rewrite ^/(.*) http://www.lianggzone.com/error.html
}
}
# 禁止访问以/data开头文件
location ~ ^/data {
deny all;
}
# 设置某些类型文件的浏览器缓存时间
location ~ .*.(gif|jpg|jpeg|png|bmp)$ {
expires 30d;
}
location ~ .*.(js|css)$ {
expires 1h;
}
# 设置过期时间不记录日志
location ~(favicon.ico) {
log_not_found off;
expires 99d;
break;
}
location ~(robots.txt) {
log_not_found off;
expires 7d;
break;
}
rewrite和return
rewrite .* http://www.baidu.com permanent;
return 301 http://ww.baidu.com
#如果你只是想要返回一定的状态码,建议用return
#如果你想要进行地址重写,建议直接用rewrite
Rewrite的四个参数
--ngx_http_rewrite_module # rewrite重写模块
1> last: # 匹配到规则重新向server发送请求,不会显示跳转之后的URL;
2> break: # 匹配到这个规则终止匹配,不再匹配后面规则;
3> redirect: # 返回302临时重定向,浏览器地址显示跳转之后URL:
# redirect一般只需要临时跳转,这些跳转需要一定时间缓冲,如果跳转过长,可能被百度判断为作弊,会被k站;
4> permanent:返回301永久重定向,浏览器地址显示跳转后URL地址;
last,break详解
mkdir test
echo break > test/break.html
echo last > test/last.html
echo test > test/test.html
vim /etc/nginx/conf.d/default.conf
location /break {
root /usr/share/nginx/html;
rewrite .* /test/break.html break;
}
location /last {
#root /usr/share/nginx/html;
rewrite .* /test/last.html last;
}
location /test {
root /usr/share/nginx/html;
rewrite .* /test/test.html break;
}
nginx -s reload
elinks --dump 49.233.69.195/last
test
elinks --dump 49.233.69.195/break
break
elinks --dump 49.233.69.195/test
test
- 如果rewrite在匹配过程中,匹配结束了就必须声明root目录的位置,并显示root位置的url,如果没有匹配完成就不需要root目录
- last标记在本条rewrite规则执行完后,会对其所在的server {...}标签重新发起请求.
- break标记则在本次规则匹配完成后,停止匹配,不再做后续的匹配.
- 有些时候必须使用last,比如使用alias指令时,而使用proxy_paas指令时必须使用break.
Nginx location优先级
= 表示精确匹配,优先级也是最高的
^~ 表示uri以某个常规字符串开头,理解为匹配url路径即可(少用)
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
!~ 表示区分大小写不匹配的正则
!~* 表示不区分大小写不匹配的正则
/ 通用匹配,任何请求都会匹配到
= 大于 ^~ 大于 ~ ~* !~ !~* 大于 /
Nginx全局变量
nginx里面的变量和shell里面的不相同,nginx里面的所有变量在定义时需要使用$变量名定义,直接写变量名表示引用变量.
1> $args # 请求中的参数,这个变量存放的是URL中的请求指令:
# 请求指令: 网址中?后面的一串字符,就是我们给网页传递过去的参数
2> $content_length # 请求长度: 存放请求报文中content_length字段内容,代表报文有点多少字节
3> $content_type # 请求类型: 存放请求报文中content_type字段内容
4> $document_root # 网页目录: 存放当前请求的根路径,对于apache来首就是/var/www/html
5> $document_uri # 存放请求报文中的当前URI,并且不包括请求指令
6> $host # 主机: 代表URI地址中的主机部分,如果请求中没有host行,则等于设置的服务器名:
7> $http_user_agent # 存放客户端代理信息(即客户端的浏览器类型)
8> $http_cookie # 开发使用,表示client和server之间的会话信息,server返回的验证身份信息的一段字符串.
# 浏览器的缓存其中一个就是cookie,这个cookie就是访问某一台web服务器,网站服务器为了验证身份生成的一段字符串.
9> $limit_rate # 用不到,nginx服务器对网络连接速率做限制的.
10> $remote_addr # 存放客户端ip地址
11> $remote_port # 存放客户端端口,即源端口: 客户端访问时,服务器收到的数据的源端口号是多少.
12> $remote_user # 远程用户: 存放客户端的用户名,基于用于密码验证的用户名.
13> $request_body_file # 表示nginx做反向代理时,nginx转给后端服务器的文件名称
14> $request_method # 存放客户端请求资源的方法,就是GET,POST,PUT,DELETE,HEAD
15> $request_filename # 存放当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images/a.jpg)
16> $request_uri # 存放当前请求的URI地址,并且带有请求指令(不带网站的主目录/images/a.jpg)
17> $query_string # 查询的字符串: 与变量$args含义相同,表示?后面一串
18> $scheme # 存放客户端请求使用的协议,如http,https
19> $server_protocol # 存放客户端请求协议的版本, http/1.0 http/1.1
20> $server_addr # 存放服务器ip地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费)
21> $server_name # 存放了客户端请求到达的服务器的名称,配置虚拟主机时的虚拟主机名
22> $server_port # 存放了客户端请求到达的服务器的端口号
23> $uri # 与变量$document_uri含义相同,代表URI地址,不包括请求指令,问好后面的不包含
Example:
if ( -f $request_filename) {.....} 如果客户端请求的文件名存在,就做什么动作
if ($request_method = POST) {.....} 如果客户端请求方法是POST上传,做什么动作
if ($http_user_agent ~ MSIE) {.....} 如果客户端的浏览器名称里面带有MSIE字符就做什么操作
04 . Nginx的Rewrite重写的更多相关文章
- nginx之rewrite重写,反向代理,负载均衡
rewrite重写(伪静态): 在地址栏输入xx.com/user-xxx.html, 实际上访问的就是xxx.com/user.php?id=xxx rewrite就这么简单 附上ecshop re ...
- Nginx实现rewrite重写
目录 Rewrite基本概述 Rewrite标记Flag Rewrite规则实践 Rewrite场景示例 Rewrite规则补充 rewrite优先级实战 Rewrite基本概述 什么是rewrite ...
- nginx的Rewrite重写
location /{ if ($remote_addr=192.168.1.100){ //禁止此 ip 访问 ...
- 第十七章 nginx动静分离和rewrite重写
一.动静分离 动静分离,通过中间件将动静分离和静态请求进行分离:通过中间件将动态请求和静态请求分离,可以减少不必要的请求消耗,同时能减少请求的延时.通过中间件将动态请求和静态请求分离,逻辑图如下: 1 ...
- nginx rewrite重写
通过官方文档可以看到,rewrite的作用上下文是 server location,可以写在 server里面 亦或location里面; 命令: if (条件) {} 条件判断 set #设置 ...
- Nginx中的 location 匹配和 rewrite 重写跳转
Nginx中的location匹配和rewrite重写跳转 1.常用的Nginx正则表达式 2.location 3.rewrite 4.rewrite实例 1.常用的Nginx正则表达式: ^ :匹 ...
- 09 nginx Rewrite(重写)详细解析
一:Rewrite(重写)详细解析 rewrite 重写 重写中用到的指令 if (条件) {} 设定条件,再进行重写 set #设置变量 return #返回状态码 break #跳出rewri ...
- nginx的URL重写应用实例
1,NGINx的URL重写 NGINX 的URL重写模块用的比较多,主要使用的命令有if rewrite set break 2 if命令 语法如下"" 语法:if(conditi ...
- Nginx 笔记与总结(12)Nginx URL Rewrite 实例(ecshop)
访问项目地址:http://192.168.254.100/ecshop 某个商品的 URL:http://192.168.254.100/ecshop/goods.php?id=3 现在需要实现把以 ...
随机推荐
- C. Cave Painting(最小公倍数的应用)
\(\color{Red}{网上的题解都是投机取巧啊,虽然也没错}\) \(Ⅰ.先说一下投机取巧的方法\) \(自己写几个例子会发现k很小的时候满足条件的n就变得很大\) \(所以我们直接暴力从1判断 ...
- 看直播 csust oj
看直播 Description 小明喜欢看直播,他订阅了很多主播,主播们有固定的直播时间 [Li, Ri] . 可是他网速只有2M,不能同时播放两个直播,所以同一时间只能看一个直播. 并且他只会去看能 ...
- spring的bean的注解配置
使用bean的方式配置spring 比较麻烦,开发的时候经常使用注解的方式配置spring. 第一步,创建java项目,导入jar包 第二步,创建spring 的主配置文件 第三步,创建实体类,加注解 ...
- java读源码 之 queue源码分析(PriorityQueue,附图)
今天要介绍的是基础容器类(为了与并发容器类区分开来而命名的名字)中的另一个成员--PriorityQueue,它的大名叫做优先级队列,想必即使没有用过也该有所耳闻吧,什么?没..没听过?emmm... ...
- 【Hadoop离线基础总结】Hue与Mysql集成
Hue与Mysql集成 1.修改hue.ini配置文件 这里要去掉#,打开mysql注释,大概在1547行 [[[mysql]]] nice_name="My SQL DB" en ...
- STM32 进行软件复位的方法
platform:stm32f103xx include:core_cm3.h /** \brief System Reset \details Initiates a system reset re ...
- linux 修改时间同步到BIOS
设置时间和日期例如:将系统日期设定成2020年4月14日的命令 命令 : "date -s 04/14/2020" 将系统时间设定成下午5点55分55秒的命令 命令 : " ...
- SSL协议握手工作流程详解(双向HTTPS流程)
参考学习文档:http://www.cnblogs.com/jifeng/archive/2010/11/30/1891779.html SSL协议的工作流程: 服务器认证阶段: 1)客户端向服务器发 ...
- Windows基础学习
0x01 常用的端口 HTTP协议代理服务器常用端口号:80/8080/3128/8081/9098SOCKS代理协议服务器常用端口号:1080FTP(文件传输)协议代理服务器常用端口号:21Teln ...
- Spring源码解析02:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析
一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...