[转帖]nginx(三十二)rewrite模块

nginx,三十二,rewrite,模块 · 浏览次数 : 0

小编点评

**301、302'响应状态码,则是内部跳转 遗留点:rewrite是否'跨域'、客户端'地址栏'的变化、发生了'几次'请求、是否记录'跳转'的日志?** 301、302响应状态码是内部跳转的指示,但由于内部跳转的场景比较复杂,可能会存在一些遗留点。 **1)案例一 重置'https://'** ``` location ~* (?!.*/wzj/favicon).*(\\.ico)$ { rewrite ^(.*) http://rewrite.wzj.com/static/wzj/favicon/favicon.ico permanent; # 备注:rewrite 'https://' -->所以下面'return 301'不会执行 return 301; } ``` **2)案例二 正则模式匹配** ``` location (^/aa/bb/cc.ico$) { rewrite ^ http://rewrite.wzj.com/static/wzj/favicon/favicon.ico permanent; } ``` **3)案例三 贪婪和非贪婪模式** ``` location (?:.*/wzj/favicon)\.(?:ico|png|jpg)$ { # 贪婪模式匹配 rewrite ^ $1 permanent; # 非贪婪模式匹配 rewrite (?:.*?(\.ico|png|jpg)) $1 permanent; } ``` **4)案例四 零宽度断言** ``` location /aa/bb/cc.ico$ { rewrite ^ http://rewrite.wzj.com/static/wzj/favicon/favicon.ico permanent; } ``` **5)案例五 贪婪和非贪婪模式的比较** ``` location /aa/bb/cc.ico$ { # 贪婪模式匹配 rewrite ^ http://rewrite.wzj.com/static/wzj/favicon/favicon.ico permanent; # 非贪婪模式匹配 rewrite (?:.*?(\.ico|png|jpg)) $1 permanent; } ```

正文

一    官方rewrite模块

①   模块涉及的指令

②   基本简介

rewrite模块会根据'PCRE正则'匹配'重写URI'

pcre下载地址

pcretest测试正则表达式

③  break

疑惑点: 结束'该作用域'下剩余的指令,还是'只是该rewrite模块的'指令?

1)配置demo

 2)不带参数请求

3)带参数请求 

  1. 由于URL中'&、&'不转义,curl请求最好加上'单引号',如果想使用'shell变量'则使用"双引号"
  2. 遗留:带参数同时配置中的'break'关闭看看效果
  3. 效果:整个请求就'被终止'了,后续的指令都'不'执行了,直接返回'404'

nginx的11个阶段

④  if

  1. if指令'掌握'两个点:'自定义[set]''内置(模块提供)'变量和'正则'形式
  2. 掌握:if (condition) {} 中'condition'的场景
  3. 遗留点:匹配后'不停止'?

 if 的 and else or 等价用法

  1. ++++++++++++++ '官方'案例 ++++++++++++++
  2. $request_filename:当前'连接请求'的文件路径,由'root''alias指令'与URI请求生成

相关案例参考 

  1. if ( $http_cookie ~* "name=wzj") -->cookie'数据太大',优点不明显
  2. if (remotr_addr ~* ^172\.25\.2\.*) -->限定'部分ip'访问
  3. ++++++++++++ server块中 ++++++++++++
  4. if ($request_uri ~ /vnc/include/(.+)) {
  5. set $parms $1;
  6. # 体会这个'含义',个人感觉是终止'server中执行rewrite的'阶段
  7. break;
  8. }
  9. location /vnc {
  10. proxy_pass http://www.wzj.com/$parms
  11. }

高级:nginx 剔除 $args 变量中任意指定参数

⑤  return

思考:'error_page''return'的优先级?

  1. 需求1: http'跳转'到https
  2. server {
  3. listen 80;
  4. server_name www.wzj.com;
  5. return 301 https://$http_host$request_uri;
  6. }
  7. +++++++++++++++ "分割线" +++++++++++++++
  8. 需求2:临时'调试'
  9. return 200 $name $request_uri;
  10. return 200 '{"name":"aming","id":"100"}'; # 返回json的形式
  11. +++++++++++++++ "分割线" +++++++++++++++
  12. 需求3:请求后缀'过滤'
  13. location ~ .*\.(sh|bash)?$ {
  14. return 403;
  15. # deny all;
  16. }
  17. +++++++++++++++ "分割线" +++++++++++++++
  18. 需求4:网站被黑了,凡是在'百度点击到本网站'的请求,全部都跳转到了一个'赌博'网站
  19. if ($http_referer ~ 'baidu.com') {
  20. return 200 "<html><script>window.location.href='//$host$request_uri';</script></html>";
  21. }

⑥  rewrite

  1. [1]. 在一个 URL 请求中,rewrite 如果'匹配到' regex,那么 URL 就会'替换'成 replacement
  2. [2]. 如果'不考虑' flag,匹配规则'多个rewrite''顺序执行'的,即使匹配到了,仍然'会继续'匹配下去
  3. [3]. 如果 replacement 包含 "http://", "https://", or "$scheme",那么匹配会'立即终止',并直接'重定向地址'给客户端
  4. ++++++++++ 'rewrite'哪些是重定向,哪些是'内部'转发 ++++++++++
  5. 1、涉及'https''http''$scheme' 都是重定向
  6. rewrite ... https|http|$scheme 这三种,默认是'redirect(302)',自己指定'permanent(301)'
  7. 特点:一旦匹配上,立即终止'处理','直接返回'给客户端'301、302',不再做后续'location'等操作,但是'content'还会执行
  8. 细节点:客户端的'地址栏'会发生变化 -->原因:浏览器根据'301、302'的状态码+'Location'响应头再发一次请求
  9. curl -Lv 查看详细'交互'过程
  10. 2、如果'replacement'不是上述的,或者不是返回给客户端'301、302'响应状态码,则是内部跳转

遗留点:rewrite是否'跨域'、客户端'地址栏'的变化、发生了'几次'请求、是否记录'跳转'的日志?

1)案例一

重写的字符串 '带http://'、不带'flag'

2)案例二

  1. 重写的字符串 '不带'http://,也不带'flag'
  2. 说明:相对于'root资源'目录

3)  nginx rewrite 中last break flag区别

  1. ++++++++++++++++++"假定rewrite在location中"++++++++++++++++++
  2. [1]. last 和 break一样 它们都会'终止'此 location 中'其它rewrite模块指令'的执行
  3. [2]. 但是 last 立即发起'新一轮'的 location 匹配 而 break'不会'
  4. 补充: 'break'跳过'当前的rewrite'阶段,并执行本请求'输出'阶段
  5. ++++++++++++++++++++++++"分割线"++++++++++++++++++++++++
  6. [1]. flag 参数'如果''redirect''permanent',那么处理就相对简单,立刻'中止规则匹配',进行 302 或 301 跳转
  7. [2]. 如果在 location 中配置 'flag 是 last',立刻'跳出本 location' 的匹配,同时会顺序'继续搜寻其他' location 的匹配,如果还'没匹配'到,还会继续'搜寻本' location
  8. [3]. 而 break '跳出本' location 后就'不会再匹配'其它 location 了

案例汇总 

  1. 1. 如果'rewrite'同一个上下文由多个这样的规则:无'https、http、$scheme',也无'flag'标识
  2. 2. 匹配会按照'rewrite'指令出现的'先后'顺序依次进行,匹配到一个后'不会终止',而是继续往下匹配,直到返回'最后一个匹配上'的为止

+++++++++++++++++"分割线1"+++++++++++++++++

+++++++++++++++++"分割线2"+++++++++++++++++

  1. +++++++++++ "思考:二者访问的区别?" +++++++++++
  2. curl -iL http://rewrite.wzj.com/b/ -->"匹配到 location /" --> 'rewrite ^/a /b last;'
  3. curl -iL http://rewrite.wzj.com/b -->"location = /b"的精确匹配
+++++++++++++++++"分割线3"+++++++++++++++++

  1. 请求: http//rewrite.wzj.com/break/xx
  2. 输出: 'break page'
  3. 分析:
  4. 1. break'跳过当前请求'的rewrite阶段,并'继续执行本请求''其他'阶段
  5. 2. 很明显,对于/break 对应的'content阶段'的输出为 echo "break page"
  6. 3. content阶段,可以简单理解为'产生数据输出的阶段',
  7. 4. echo指令也是'运行在content阶段',一般情况下content阶段只能对应一个输出指令,如同一个location'配置两个echo',最终只会有一个echo指令被执行
  8. 5. 当然如果你把'/break/'里的'echo 指令注释',然后再次访问/break/xx会'报404'
  9. 6. 虽然/break/xx'被重定向'到/test/xx,但是break指令'不会重新开启一个新的请求'继续匹配,所以nginx是'不会匹配到下面'的/test/这个location
  10. 7. 在echo指令'被注释'的情况下,/break/ 这location里'只能执行'nginx默认的content指令,即'尝试找/test/xx这个html页面'并输出起内容,事实上,这个页面'不存在',所以会报404的错误。
  11. ++++++++++++++ "分割线" ++++++++++++++
  12. 请求: http//rewrite.wzj.com/last/xx
  13. 输出: 'test page'
  14. 分析:
  15. 1. last与break最大的'不同'是,last会'重新发起'一个新请求,并'重新匹配'location
  16. 2. 所以对于/last,重新匹配请求以后'会匹配到/test/',所以最终'对应的content阶段'的输出是test page;

echo模块源码安装 

4) 死循环场景

5)查询参数

  1. 1. rewrite /a.html /new permanent -->重定向'带原始参数'的地址
  2. 2. rewrite /a.html /new? permanent -->重定向'不带'参数
  3. 3. rewrite /a.html /new?age=18 permanent -->重定向'追加'查询参数
  4. 4. rewrite /a.html /new?id=$arg_id&name=$arg_name? permanent -->重定向只'带指定'参数

return, rewrite, and try_files对比 辅助参考

⑦  rewrite_log 

error.log开启'notice'级别,默认是'error'

 ⑧  set

细节点: 除了'变量$args'可以被'修改'以外,其'对应的子变量值'都只能'被查看''不能'进行修改

 作用域问题

⑨   uninitialized_variable_warn

⑩  遗留

  1. 1. 使用 alias 指令时,必须使用 last;
  2. 2. 使用 proxy_pass 指令时,则必须使用break

二   高级正则

①  普通补获

捕获 (exp) :匹配exp,并捕获文本到'自动命名$1、$2、...$9'的组里 --> "常见"

  1. +++++++++++ 'http跳转到https' +++++++++++
  2. server {
  3. listen 80;
  4. server_name www.wzj.com ;
  5. rewrite ^(.*) http://www.wzj.com$1 permanent;
  6. }

②  命名捕获

  1. (?<name>exp):匹配exp,并'捕获文本'到名称为'name的组'里,也可以写成(?'name'exp)
  2. 说明:能'看懂'即可

  

③   非补获

  1. ​1. 语法:(?:pattern)
  2. 2. 解读:'非获取匹配','匹配'pattern但'不获取'匹配结果,'不进行存储'供以后使用
  3. 3. 这在使用或字符"(|)"来组合一个'模式''各个部分'是很有用
  4. 4. 例如:'industr(?:y|ies)'就是一个比'industry|industries'更简略的表达式
  5. ++++++++++ "案例讲解" ++++++++++
  6. if ($uri ~* \.(?:html|css|js|json)$){
  7. proxy_pass http://static/wzj.com
  8. }
  9. +++++++++ nginx自行对"/"处理 +++++++++
  10. ~* ^\/wzj\/(.+?\.(?:html|css|js))$
  11. 说明:'/'不需要跟'shell'正则一样转义,nginx会'自行'处理

.*、.*?、.+?的含义

④  零宽度断言 

shell常用正则表达式

  1. 四个'非捕获组'用于匹配pattern'或者'不匹配pattern位置'之前''之后'的内容,匹配的结果'不包括'pattern
  2. 补充:(?#comment),这种类型的分组'不对'正则表达式的处理产生任何影响,用于'提供注释'让人阅读

 1)案例一

  1. location ~* (?!.*/wzj/favicon).*(\.ico)$ {
  2. rewrite ^(.*) http://rewrite.wzj.com/static/wzj/favicon/favicon.ico permanent;
  3. # 备注:rewrite 'https://' --> 所以下面'return 301'不会执行
  4. return 301;
  5. }

  1. [1]. $request_uri'待匹配'的字符串
  2. http://rewrite.wzj.com'/aa/bb/cc.ico'
  3. http://rewrite.wzj.com'/wzj/favicon/favicon.ico'
  4. http://rewrite.wzj.com'/wzj/favicon/favicon.txt'
  5. [2]. (?!.*/wzj/favicon).*(\.ico)$ 是'正则模式'

遗留点:'回溯'的过程?

⑤  贪婪非贪婪模式

浅谈nginx反向代理中神奇的斜线  整理的案例

break和last理解

rewrite官方的一些案例

三    rewrite案例 遗留

常见情形

websocket官方配置  -->专栏

internal 指令限制访问图片资源文件

 nginx internal 语法 – SRE笔记

  internal官方文档应用场景

nginx的重定向和内部转发location @ internal

rewrite其它域名、内部请求

nginx常见的rewrite规则、location稍后补充下

  1. 1. 执行server块的rewrite指令
  2. 2. 执行location匹配
  3. 3. 执行选定的location中的rewrite指令

与[转帖]nginx(三十二)rewrite模块相似的内容:

[转帖]nginx(三十二)rewrite模块

一 官方rewrite模块 ① 模块涉及的指令 ② 基本简介 rewrite模块会根据'PCRE正则'匹配'重写URI' pcre下载地址 pcretest测试正则表达式 ③ break 疑惑点: 结束'该作用域'下剩余的指令,还是'只是该rewrite模块的'指令? 1)配置demo 2)不带参数

[转帖]nginx(三十四)root和alias指令辨析

一 root指令 ① 案例一 简单 $uri:'/resource/href.html' location:'/resource' -- 强调:location'只能'匹配uri,'不能'匹配'参数' 最终'资源'文件:/usr/share/nginx/html/resource/href.html

[转帖]Nginx(四)负载均衡

一 nginx目录的说明 1 nginx/ 3 |-- client_body_temp 4 |-- conf #这是Nginx所有配置文件的目录,极其重要 5 | |-- fastcgi.conf 'fastcgi相关参数的配置文件' 6 | |-- fastcgi.conf.default #f

[转帖]nginx限速

https://www.cnblogs.com/fengzi7314/p/16541440.html 第一步,先创建限制的规则,我这里直接在nginx默认的配置文件目录下配置,如果想自定义,需要在主配置文件添加include xx/xxx/xxx/*.conf配置 [root@node5 nginx

[转帖]Nginx支持WebSocket反向代理

https://www.cnblogs.com/zhengchunyuan/p/12923692.html WebSocket是目前比较成熟的技术了,WebSocket协议为创建客户端和服务器端需要实时双向通讯的webapp提供了一个选择。其为HTML5的一部分,WebSocket相较于原来开发这类

[转帖]Nginx内置变量以及日志格式变量参数详解

补充 $args #请求中的参数值 $query_string #同 $args $arg_NAME #GET请求中NAME的值 $is_args #如果请求中有参数,值为"?",否则为空字符串 $uri #请求中的当前URI(不带请求参数,参数位于$args),可以不同于浏览器传递的$reques

[转帖]nginx proxy_pass keepalive

Syntax: keepalive connections; Default: — Context: upstream This directive appeared in version 1.1.4. Activates the cache for connections to upstream

[转帖]Nginx超时timeout 设置

Nginx 超时配置,连接时间过长直接关闭连接,显示timeout http { #每个 TCP 连接最多可以保持多长时间 keepalive_timeout 60; #客户端向服务端发送一个完整的 request header client_header_timeout 10; #客户端发送服务端

[转帖]nginx反向代理时保持长连接

https://www.cnblogs.com/liufarui/p/11075630.html ·【场景描述】 HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。 如果我们使用了nginx去作为反

[转帖]Nginx报错404,由于请求处理时间过长

问题复现 近期部门内部有一个应用由于数据量过于庞大,或者说sql优化性能问题,导致查询全量数据时老报错nginx404,后来查看浏览器timing信息,发现其竟然时常达到可怕的2分钟十秒,抛去解决sql优化问题,这里从Nginx端的配置来说如何解决这类问题! 存在的问题 服务器处理请求时间过长,导致