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标记有:

  1. last: 相当于Apache里的[L]标记,表示终止继续在本location快中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用下一个location块进行处理,处理完成再从第一个location开始,循环五次报500错误.

  2. break: 将此处重写的URI作为一个新的URI,在本块中继续进行处理,该标识将重写后的地址在当前location块中执行,不会将新的URI转向到其他location块.

  3. redirect: 返回302临时重定向,浏览器地址会显示跳转后的URL地址.

  4. 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
  1. 如果rewrite在匹配过程中,匹配结束了就必须声明root目录的位置,并显示root位置的url,如果没有匹配完成就不需要root目录
  2. last标记在本条rewrite规则执行完后,会对其所在的server {...}标签重新发起请求.
  3. break标记则在本次规则匹配完成后,停止匹配,不再做后续的匹配.
  4. 有些时候必须使用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重写的更多相关文章

  1. nginx之rewrite重写,反向代理,负载均衡

    rewrite重写(伪静态): 在地址栏输入xx.com/user-xxx.html, 实际上访问的就是xxx.com/user.php?id=xxx rewrite就这么简单 附上ecshop re ...

  2. Nginx实现rewrite重写

    目录 Rewrite基本概述 Rewrite标记Flag Rewrite规则实践 Rewrite场景示例 Rewrite规则补充 rewrite优先级实战 Rewrite基本概述 什么是rewrite ...

  3. nginx的Rewrite重写

        location /{                if ($remote_addr=192.168.1.100){                          //禁止此 ip 访问 ...

  4. 第十七章 nginx动静分离和rewrite重写

    一.动静分离 动静分离,通过中间件将动静分离和静态请求进行分离:通过中间件将动态请求和静态请求分离,可以减少不必要的请求消耗,同时能减少请求的延时.通过中间件将动态请求和静态请求分离,逻辑图如下: 1 ...

  5. nginx rewrite重写

    通过官方文档可以看到,rewrite的作用上下文是   server location,可以写在 server里面  亦或location里面; 命令: if (条件) {} 条件判断 set #设置 ...

  6. Nginx中的 location 匹配和 rewrite 重写跳转

    Nginx中的location匹配和rewrite重写跳转 1.常用的Nginx正则表达式 2.location 3.rewrite 4.rewrite实例 1.常用的Nginx正则表达式: ^ :匹 ...

  7. 09 nginx Rewrite(重写)详细解析

    一:Rewrite(重写)详细解析 rewrite 重写 重写中用到的指令 if  (条件) {}  设定条件,再进行重写 set #设置变量 return #返回状态码 break #跳出rewri ...

  8. nginx的URL重写应用实例

    1,NGINx的URL重写 NGINX 的URL重写模块用的比较多,主要使用的命令有if rewrite set break 2 if命令 语法如下"" 语法:if(conditi ...

  9. Nginx 笔记与总结(12)Nginx URL Rewrite 实例(ecshop)

    访问项目地址:http://192.168.254.100/ecshop 某个商品的 URL:http://192.168.254.100/ecshop/goods.php?id=3 现在需要实现把以 ...

随机推荐

  1. Shell脚本(一)入门

    开始学习Shell脚本. #!/bin/bash ]; then echo "you are not root" else echo "you are root" ...

  2. Java 函数式接口

    目录 Java 函数式接口 1. 函数式接口 1.1 概念 1.2 格式 1.3 函数式接口的使用 2. 函数式编程 2.1 Lambda的延迟执行 性能浪费的日志案例 使用Lambda表达式的优化 ...

  3. 王颖奇 20171010129《面向对象程序设计(java)》第十四周学习总结

    实验十四  Swing图形界面组件 理论知识知识点: 1.Swing和MVC设计模式2.布局管理器3.文本输入4.选择组件5.菜单6.对话框 实验时间 2018-11-29 1.实验目的与要求 (1) ...

  4. 【Hadoop离线基础总结】oozie调度MapReduce任务

    目录 1.准备MR执行的数据 2.执行官方测试案例 3.准备我们调度的资源 4.修改配置文件 5.上传调度任务到hdfs对应目录 6.执行调度任务 1.准备MR执行的数据 MR的程序可以是自己写的,也 ...

  5. MOS管、PCB、H桥、步进电机驱动电路、51单片机的IO口驱动能力、灌电流、拉电流、上拉电阻的选择

    嵌入式开发PCB设计几点体会(转载):http://bbs.ednchina.com/BLOG_ARTICLE_3021801.HTMCollector-Emitter Saturation Volt ...

  6. [hdu5256]LIS模型

    题目:有一个数列A1,A2...An,修改数量最少的元素,使得这个数列严格递增.无论是修改前还是修改后,每个元素都必须是整数. 思路: 修改数量最少的元素使得这个数列严格递增,等价于让数量最多的元素不 ...

  7. [csu/coj 1078]多个序列的最长公共子序列

    题意:给n个序列,同一个序列里面元素互不相同,求它们的最长公共子序列. 思路:任取一个序列,对于这个序列里面的两个数ai,aj(i<j),如果对于其它每一个序列,都出现过ai,aj,且ai在aj ...

  8. 上位机开发之三菱Q系列PLC通信实践

    经常关注我们公众号或者公开课的学员(如果还没有关注的话,左上角点击一波关注)应该知道,我们会经常使用西门子PLC,其实对于其他品牌的PLC,我们都会讲到,包括三菱.欧姆龙.基恩士.松下及国产台达.信捷 ...

  9. git 常用 指令累积

    1.查询指定文件的修改所有修改日志git log --pretty=oneline 文件名 1. git log filename 可以看到fileName相关的commit记录2. git log ...

  10. 自己用C语言写NXP S32K144 serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader) 欢迎咨询或定制bootloader(在线升级程序). NXP S32K144 ...