惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Jina AI
Jina AI
IT之家
IT之家
J
Java Code Geeks
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
量子位
I
InfoQ
博客园 - 【当耐特】
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
V
V2EX
博客园 - Franky
U
Unit 42
S
SegmentFault 最新的问题
美团技术团队
The Register - Security
The Register - Security
Last Week in AI
Last Week in AI
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
M
MIT News - Artificial intelligence
博客园 - 聂微东
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Troy Hunt's Blog
B
Blog
P
Palo Alto Networks Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy International News Feed
K
Kaspersky official blog
The GitHub Blog
The GitHub Blog
C
Cisco Blogs
Microsoft Azure Blog
Microsoft Azure Blog
F
Fortinet All Blogs
S
Schneier on Security
C
CERT Recently Published Vulnerability Notes
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Engineering at Meta
Engineering at Meta
TaoSecurity Blog
TaoSecurity Blog
小众软件
小众软件
T
Threatpost
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Martin Fowler
Martin Fowler
AWS News Blog
AWS News Blog
V
Visual Studio Blog
Simon Willison's Weblog
Simon Willison's Weblog
H
Heimdal Security Blog

博客园 - oec2003

读《有效需求分析》 重读《打造 Facebook》 dotNet Core 3.1 使用 Aspose (部署 Docker) 为什么这么忙,还依然做不好事情? dotNET Core:编码规范 程序员是终身学习的职业,应该怎么学习? 一款用了就不想走的工具 dotNET:怎样处理程序中的异常(实战篇)? dotNET:怎样处理程序中的异常(理论篇)? 如何激发团队潜能? dotNET Core 3.X 使用 Autofac 来增强依赖注入 dotNET Core 3.X 依赖注入 读《鞋狗》 Jenkins 中以构建 Tag 来实现版本管理 dotNET Core 3.X 使用 Jwt 实现接口认证 dotNET Core 3.X 请求处理管道和中间件 dotNET Core 3.X 使用 Web API 程序员还有35岁的坎吗? 远程办公也可以高效
Nginx:rewrite 的几个技巧
oec2003 · 2020-07-06 · via 博客园 - oec2003

在软件的发布中,我们经常会使用到 Nginx,Nginx 的功能非常的庞杂,其中 rewrite 是一个非常常用的功能模块,本文介绍 rewrite 的基本概念和几个小技巧。

rewrite 是 Nginx 中的一个模块,这个模块用来重定向页面,在 rewrite 模块中包含了几个指令来实现不同的功能:

  • return
  • rewrite
  • if

return 指令

return 指令是 rewrite 模块中非常常用的一个指令,可以帮助我们做重定向和一些简单的返回。

语法

return code text;
return code URL;
return URL;

return 指令的语法由两个或三个部分组成:

  • return: 关键字
  • code:http 状态码,当没有设置 code 时,默认使用 302
  • text 或 URL:返回的字符串或跳转的地址

使用范围

  • server 节点
  • location 节点
  • if 块中

  • 在 server 节点中的 return 的优先级要高于 location 节点的 return,不管 return 指令写在 location 节点的上方还是下方
  • 在 return 指令中使用 code,经常会用到 301 或 302 ,区别如下:
    • 301:永久重定向,例如访问 a.com,通过 return 使用 301 重定向到了 b.com,然后修改 return 的地址为 c.com,访问 a.com,还是访问的 b.com,因为被缓存了
    • 302:临时重定向,例如访问 a.com,通过 return 使用 302 重定向到了 b.com,然后修改 return 的地址为 c.com,访问 a.com,会跳转到 c.com,不会被缓存

rewrite 指令

可以根据指定的正则表达式将用户请求的 url 转换成一个新的 url 进行重定向。

语法

rewrite regex replacement [flag];

return 指令的语法四个部分组成:

  • rewrite: 关键字
  • regex:正则表达式,用于匹配用户请求的 url 地址
  • replacement:新的 url 地址,当地址开头为 http 或 https ,默认为 302 重定向
  • flag:替换后的 url 根据 flag 进行处理,flag 有四个值
    • last:使用 replacement 的地址重新进行 location 匹配
    • break:会停止后面脚本的执行
    • redirect:返回 302 重定向,地址栏显示重定向后的url
    • permanent:返回 301 重定向,地址栏显示重定向后的url

使用范围

  • server 节点
  • location 节点
  • if 块中

  • rewrite 指令的适用范围和 return 指令的是一致的,优先级也相同
  • 当 rewrite 指令和 return 指令同时存在时,如果 rewrite 最后的 flag 不是 break,会继续执行 rewrite 之后的 return 指令
  • 没有指定 flag 的情况下,默认为 302 重定向

if 指令

通过 if 指令进行一些条件的判断,然后进行 return、rewrite 或是其他的一些处理。

语法

if(condition){
}

使用范围

  • server 节点
  • location 节点

if 判断的一些规则

  • 变量和字符串做比较,使用 = 或 !=
  • 将变量和正则表达式做比较:
    • 大小写敏感:~ 或 !~
    • 大小写不敏感:~* 或 !~* ,例如上图中的示例
  • 检查文件是否存在,使用 -f 或 !-f
  • 检查目录是否存在,使用 -d 或 !-d

示例

下面以近期用到的两个场景来演示实际的用法。

PC 端跳转到移动端

场景描述:

  • PC 端发布后的地址为:192.168.0.1
  • 移动端采用 H5 开发,发布后的地址:192.168.0.1:81
  • 在手机上访问 PC 端地址,跳转到移动端
  • PC 端和移动端使用同一个接口地址,接口地址是在 PC 端使用 /api 进行的代理
  • 只有页面的请求跳转到移动端,接口的请求不需要跳转

配置如下:

server {
    listen       80;
    server_name  localhost;

    set $flag 0;

    if ($http_user_agent ~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry) ) {
      set $flag "${flag}1";
    }

    if ($request_uri !~* /api/) {
      set $flag "${flag}2";
    }

    if ($flag = "012") {
       rewrite  ^(.*)    http://192.168.0.1:81? permanent;
    }

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /api/ {
      proxy_pass http://192.168.0.1:5000/;
    }

    error_page   500 502 503 504  /50x.html;
}
  • 两个条件都满足的情况下,进行跳转
    • 设备类型为移动端
    • 请求的路由中不包含 /api
  • 因为 if 指令的条件的限制,不能再一个 condition 中使用多条件,所以定义了一个变量 $flag 来做判断

将源地址中的特定参数传递到目标地址

场景描述:

  • 上面的示例中,跳转到移动端后进入的是移动端的登录页面,因为没有登录人的身份
  • 现在假设 PC 端的地址后有 authcode 的参数用来确定身份,除此之外还有其他的参数,例如:http://192.168.0.1?id=xxxxx&authcode=xxxxxxxx
  • 需要再跳转后将 authcode 传递到移动端的地址后面,例如:http://192.168.0.1:81?authcode=xxxxxxxx 移动端可以做解析实现直接登录

配置如下: