当运维遇到要重写情况时,往往是要程序员把重写规则写好后,发给你,你再到生产环境下配置。对于重写规则说到底就是正则匹配,做运维的岂能对正则表达式不 了解的?最起码最基本的正则表达式会写。套用一句阿里的话(某网友说是阿里说的,不清楚到底是不是出自阿里)“不懂程序的运维,不是好运维;不懂运维的开 发,不是好开发。”。 正则表达式也是一门语言哈。当你学习一门语言时,必然会遇到该门语言的正则表达式这章节的。 在这里推荐一本非常好的正则表达式书,包含常用的语言的正则写法如sed、perl、bash、awk、php、c#、java、javascript、 python、ruby等等,《Regular Expressions Cookbook, 2nd Edition》,也有中文版的,大家可以到网络上找找。

一. rewrite模块介绍

nginx的重写模块是一个简单的正则表达式匹配与一个虚拟堆叠机结合。依赖于PCRE库,因此需要安装pcre。根据相关变量重定向和选择不同的配置, 从一个location跳转到另一个location,不过这样的循环最多可以执行10次,超过后nginx将返回500错误。同时,重写模块包含set 指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。

二. rewrite模块指令

break

语法:break

默认值:none

使用字段:server, location, if

完成当前设置的重写规则,停止执行其他的重写规则。

if

语法:if (condition) { … }

默认值:none

使用字段:server, location

注意:尽量考虑使用try_files代替。判断的条件可以有以下值:

  1. 一个变量的名称:空字符传“”或者一些“0”开始的字符串为false。

  2. 字符串比较:使用=或!=运算符

  3. 正则表达式匹配:使用~(区分大小写)和~*(不区分大小写),取反运算!~和!~*。

  4. 文件是否存在:使用-f和!-f操作符

  5. 目录是否存在:使用-d和!-d操作符

  6. 文件、目录、符号链接是否存在:使用-e和!-e操作符

  7. 文件是否可执行:使用-x和!-x操作符

return

语法:return code

默认值:none

使用字段:server, location, if

停 止处理并为客户端返回状态码。非标准的444状态码将关闭连接,不发送任何响应头。可以使用的状态码 有:204,400,402-406,408,410, 411, 413, 416与500-504。如果状态码附带文字段落,该文本将被放置在响应主体。相反,如果状态码后面是一个URL,该URL将成为location头补 值。没有状态码的URL将被视为一个302状态码。

rewrite

语法:rewrite regex replacement flag

默认值:none

使用字段:server, location, if

按照相关的正则表达式与字符串修改URI,指令按照在配置文件中出现的顺序执行。可以在重写指令后面添加标记。

注意:如果替换的字符串以http://开头,请求将被重定向,并且不再执行多余的rewrite指令。

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

  • last – 停止处理重写模块指令,之后搜索location与更改后的URI匹配。

  • break – 完成重写指令。

  • redirect – 返回302临时重定向,如果替换字段用http://开头则被使用。

  • permanent – 返回301永久重定向。

rewrite_log

语法:rewrite_log on | off

默认值:rewrite_log off

使用字段:server, location, if

变量:无

启用时将在error log中记录notice级别的重写日志。

set

语法:set variable value

默认值:none

使用字段:server, location, if

为给定的变量设置一个特定值。

uninitialized_variable_warn

语法:uninitialized_variable_warn on|off

默认值:uninitialized_variable_warn on

使用字段:http, server, location, if

控制是否记录未初始化变量的警告信息。

三. 重写规则组成部分

3.1 任何重写规则的第一部分都是一个正则表达式

可以使用括号来捕获,后续可以根据位置来将其引用,位置变量值取决于捕获正则表达式中的顺序,$1引用第一个括号中的值,$2引用第二个括号中的值,以此类推。如:

^/p_w_picpaths/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$

$1是两个小写字母组成的字符串,$2是由小写字母和0到9的数字组成的5个字符的字符串,$3将是个文件名,$4是png、jpg、gif中的其中一个。

3.2 重写规则的第二部分是URI

请求被改写。该URI可能包含正则表达式中的捕获的位置参数或这个级别下的nginx任何配置变量。如:

/data?file=$3.$4

如果这个URI不匹配nginx配置的任何location,那么将给客户端返回301(永久重定向)或302(临时重定向)的状态码来表示重定向类型。该状态码可以通过第三个参数来明确指定。

3.3 重写规则的第三部分

第三部分也就是尾部的标记(flag)。 last标记将导致重写后的URI搜索匹配nginx的其他location,最多可循环10次。如:

rewrite '^/p_w_picpaths/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4 last;

break指令可以当做自身指令。如:

if ($bwhog) {
limit_rate 300k;
break;
}

另一个停止重写模块处理指令是return, 来控制主HTTP模块处理请求。 这意味着,nginx直接返回信息给客户端,与error_page结合为客户端呈现格式化的HTML页面或激活不同的模块来完成请求。如果状态码附带文 字段落,该文本将被放置在响应主体。相反,如果状态码后面是一个URL,该URL将成为location头补值。没有状态码的URL将被视为一个302状 态码。如:

location = /p_w_picpath404.html {
return 404 "p_w_picpath not found\n";
}

四. 实例

http {# 定义p_w_picpath日志格式log_format p_w_picpathlog '[$time_local] ' $p_w_picpath_file ' ' $p_w_picpath_type ' ' $body_bytes_sent ' ' $status;# 开启重写日志rewrite_log on;server {        root /home/www;location / {            # 重写规则信息error_log logs/rewrite.log notice;# 注意这里要用‘’单引号引起来,避免{}rewrite '^/p_w_picpaths/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;# 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行set $p_w_picpath_file $3;            set $p_w_picpath_type $4;}location /data {# 指定针对图片的日志格式,来分析图片类型和大小access_log logs/p_w_picpaths.log main;root /data/p_w_picpaths;# 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里try_files /$arg_file /p_w_picpath404.html;        }location = /p_w_picpath404.html {# 图片不存在返回特定的信息return 404 "p_w_picpath not found\n";}}

五. 创建新的重新规则

在接到要创建新的重写规则时,要弄清楚需求是什么样的,再决定怎么做。毕竟重写也是耗资源的有效率之分的。 下面的这些问题有些帮助的:

  1. 你的URL的模式是什么样的?

  2. 是否有一个以上的方法来实现?

  3. 是否需要捕获URL部分作为变量?

  4. 重定向到另一个web上可以看到我的规则?

  5. 是否要替换查询的字符串参数?

检查网站或应用程序布局,清楚URL模式。啰嗦一句:我一而再再而三的强调,运维不能与开发脱节,运维要参与到开发当中。如果有不止一种方法实现,创建一个永久重定向。同时,定义一个重写规范,来使网址清洁,还可以帮助网站更容易被找到。

实例1. 要将home目录重定向到主页面上,目录结构如下:

/
/home
/home/
/home/index
/home/index/
/index
/index.php
/index.php/

重写规则如下:

rewrite ^/(home(/index)?|index(\.php)?)/?$ $scheme:
//$host/ permanent;

指定$scheme和$host变量,因为要做一个永久重定向并希望nginx使用相同的参数来构造URL。

实例2. 如果想分别记录各个部分的URL,可以使用正则表达式来捕获URI,然后,给变量分配指定位置变量,见上面的实例。

实例3. 当重写规则导致内部重定向或指示客户端调用该规则本身被定义的location时,必须采取特殊的动作来避免重写循环。如:在server配置段定义了一条规则带上last标志,在引用location时,必须使用break标志。

server {rewrite ^(/p_w_picpaths)/(.*)\.(png|jpg|gif)$ $1/$3/$2.$3 last;location /p_w_picpaths/ {rewrite ^(/p_w_picpaths)/(.*)\.(png|jpg|gif)$ $1/$3/$2.$3 break;}}

实例4. 作为重写规则的一部分,传递新的查询字符串参数是使用重写规则的目标之一。 如:

rewrite ^/p_w_picpaths/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&
height=$3? last;

nginx重写规则说起来挺简单的,做起来就难,重点在于正则表达式,同时,还需要考虑到nginx执行顺序。

原文:http://www.ttlsa.com/nginx/nginx-rewriting-rules-guide/

本文转自:Linux中国

转载于:https://blog.51cto.com/kaibinyuan/1635691

Nginx重写规则指南相关推荐

  1. Nginx 重写规则指南

    当运维遇到要重写情况时,往往是要程序员把重写规则写好后,发给你,你再到生产环境下配置.对于重写规则说到底就是正则匹配,做运维的岂能对正则表达式不了解的?最起码最基本的正则表达式会写.套用一句阿里的话( ...

  2. 修改thinkphp配置nginx服务器,thinkphp5.0配置nginx重写规则

    thinkphp5.0配置nginx重写规则 2018年07月06日 09:29:03阅读数:1529 server { listen 80; #端口号 server_name demo.aa.com ...

  3. Nginx 入门指南

    Nginx 入门指南 简介: Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,其特点是占有内存少,并发能力强.本教程根据淘宝核心系统服务器平台组的 ...

  4. nginx指定配置文件启动_【第1717期】Nginx入门指南

    前言 Nginx有在部署早读课网站的时候用到,平时用的不多,又是一个可以顺便了解的知识点.那个@李晓云,这篇是你想了解的吗?今日早读文章由@慕小白翻译分享. 正文从这开始-- 这份指南是对nginx的 ...

  5. 连前端都看得懂的《Nginx 入门指南》

    虽然题目看起来有点像写给前端同学的一样,但是本文实际上是适合所有想学习 Nginx 但不知道如何下手的同学.笔者尽量深入浅出,讲得通俗易懂,让在座的不管是前端还是后端,阅读体验都如德芙巧克力般丝滑. ...

  6. Nginx实用指南V1 (连载之四:流行CMS博客rewrite写法)

    Nginx Rewirte 1. 基本标记.正则.文件与目录 A.基本标记 last - 基本上都用这个Flag. ※相当于Apache里的[L]标记,表示完成rewrite,不再匹配后面的规则 br ...

  7. Nginx实用指南V1 (连载之六:cacti监控)

    申明:本连载的文章来自:Nginx官网.张 宴BLOG.linuxtone论坛.互联网.本人原创.并尽力在官网文档的基础发表原创作品.并保证文档的质量与错误率.如有作者认为本文有涉及版权问 题请与我联 ...

  8. nginx怎么升级php的版本号,nginx 升级指南,最详细的nginx升级步骤

    查看nginx当前版本 通过nginx -V 命令就可以查看当前的版本,已经当前版本安装时候的一些nginx命令 [root@localhost sbin]# ./nginx -V nginx ver ...

  9. 高性能Web服务器Nginx使用指南

    Nginx是一个高性能的http服务器和反向代理服务器,是一个高度模块化的web服务器,和Apache的模块化不同,Nginx的模块不支持动态编译,Nginx要加入新的第三方模块的时候,必须先下载模块 ...

最新文章

  1. python核心编程——python对象
  2. 微信授权获取用户openid前端实现
  3. Maven项目中使用本地JAR包
  4. (转)Spring4.2.5+Hibernate4.3.11+Struts2.3.24整合开发
  5. 【Flink】JobManager responsible for xx lost the leadership zk变动导致重启
  6. 在线HTML转JSX工具
  7. 大牛精心挑选的25个Visual Basic学习资料汇总
  8. [Android Security] DEX文件格式分析
  9. linux 修改文件日期,Linux中使用touch命令来修改文件的时间
  10. 图书馆管理系统(连接数据库)
  11. java dom4j解析复杂xml成json
  12. ros打开笔记本电脑的摄像头
  13. win10安装opencv,pycharm中import cv2失败
  14. 特殊格式的时间读取并排序
  15. Linux网络与配置
  16. 嵌入式Linux_USB_U盘自动检测识别
  17. 解析SCUT FIR Pedestrian Dataset数据
  18. dubbo消费端如何找到服务端对象,进行方法调用的
  19. spring cloud alibaba 全家桶详细整合
  20. python 將‘Sun May 01 21:48:58 2022‘格式的日期转为2022-05-01 21:48:58

热门文章

  1. 让IE支持Css3属性(圆角、阴影、渐变)
  2. Linux内核分析-week 1
  3. Linux下动态共享库加载及使用详解
  4. C语言实现简单学籍管理系统
  5. HadoopDB GlobalHasher的参数问题
  6. String(+) vs StringBuffer(append)
  7. 输入用户名和密码登入到服务器,却显示指定的网络密码不正确,输入了好几次都是这样,这是怎么回事? 用户名和密码没问题 ,一直用的好好地今天就不行了...
  8. 关于IPMI的几个问题
  9. mui调本地相册上传图片
  10. java 开发银行支付、对账时证书相关的操作总结