# Nginx Rewrite 场景实战
# 1.Rewrite 基本介绍
# 1.1 什么是 Rewrite
Rewrite 主要实现 url 地址重写, 以及 url 地址跳转。就是将用户请求 web 服务器的 URL 地址重新修改为其他 URL 地址的过程。
比如说京东,google、亚马逊都在使用
# 1.2 Rewrite 应用场景
- 1. 地址跳转,用户访问 www.jd.com 这个 URL 时,将其定向至一个新的域名 m.jd.com
- 2. 协议跳转,将用户通过 http 的请求协议重新跳转至 https 协议 (实现 https 主要手段)。
- 3.URL 静态化,将动态 URL 地址显示为静态 URL 的一种技术,能提高搜索引擎抓取,并且能减少动态 URL 对外暴露过多的参数。
# 1.3 Rewrite 重写原理
![2.png]()
# 1.4 Rewrite 重写模块
- set 设置变量
- if 语句判断
- return 返回返回值或 URL
- rewrite 重定向 URL
# 2.Rewrite 重写模块
# 2.1 if 条件判断指令
# 2.1.1 语法示例
| Syntax: if (condition) { ... } |
| Default: — |
| Context: server, location |
| |
| |
| |
| |
| |
# 2.1.2 场景示例
| url.hmallleasing.com/index.html?id=1234 --》 proxy-->192.168.1.8:8080 |
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| default_type application/json; |
| root /code; |
| |
| location / { |
| index index.html; |
| |
| if ( $request_uri ~* 'id=\d{4}' ) { |
| proxy_pass http://192.168.1.8:8080; |
| } |
| } |
| } |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
# 2.2 set 设定变量指令
# 2.2.1 语法示例
| Syntax: set $variable value; |
| Default: — |
| Context: server, location, if |
# 2.2.2 场景示例
| |
| |
| |
| |
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| index index.html; |
| |
| location / { |
| if ($http_user_agent ~* "firefox|curl|Wget|ApacheBench") { |
| set $deny_user_agent 1; |
| } |
| if ($deny_user_agent = 1){ |
| return 403; |
| } |
| } |
| } |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| |
| |
| [root@web01 conf.d] |
| HTTP/1.1 403 Forbidden |
| Server: nginx/1.26.1 |
| Date: Thu, 04 Sep 2025 07:36:43 GMT |
| Content-Type: text/html |
| Content-Length: 153 |
| Connection: keep-alive |
| |
| |
| [root@web01 conf.d] |
| HTTP/1.1 200 OK |
| Server: nginx/1.26.1 |
| Date: Thu, 04 Sep 2025 07:37:42 GMT |
| Content-Type: text/html |
| Content-Length: 6 |
| Last-Modified: Thu, 04 Sep 2025 07:32:58 GMT |
| Connection: keep-alive |
| ETag: "68b940aa-6" |
| Accept-Ranges: bytes |
# 2.3 return 返回数据指令
# 2.3.1 语法示例
| Syntax: return code; |
| return code [text]; |
| return URL; |
| Default: — |
| Context: server, location, if |
# 2.3.2 场景实践
| |
| [root@web01] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| index index.html; |
| default_type text/html; |
| if ( $http_user_agent ~* "MSIE|firefox" ) { |
| |
| return 200 "Change browser"; |
| |
| return 500; |
| |
| return 302 https://www.jd.com |
| } |
| } |
| } |
| |
| |
| [root@web01 conf.d] |
| Change browser |
| |
| |
| [root@web01 conf.d] |
| HTTP/1.1 500 Internal Server Error |
| Server: nginx/1.26.1 |
| Date: Thu, 04 Sep 2025 07:52:36 GMT |
| Content-Type: text/html |
| Content-Length: 177 |
| Connection: close |
| |
| |
| [root@web01 conf.d] |
| HTTP/1.1 302 Moved Temporarily |
| Server: nginx/1.26.1 |
| Date: Thu, 04 Sep 2025 07:51:32 GMT |
| Content-Type: text/html |
| Content-Length: 145 |
| Connection: keep-alive |
| Location: http://www.qq.com |
| |
| HTTP/1.1 302 Moved Temporarily |
| Server: stgw |
| Date: Thu, 04 Sep 2025 07:51:52 GMT |
| Content-Type: text/html |
| Content-Length: 137 |
| Connection: keep-alive |
| Location: https://www.qq.com/ |
| |
| HTTP/1.1 200 OK |
| Date: Thu, 04 Sep 2025 07:51:52 GMT |
| Content-Type: text/plain; charset=utf-8 |
| Content-Length: 0 |
| Connection: keep-alive |
| Server: tRPC-Gateway |
| Inews_trace_id: 40396647090904155152 |
| Inews-Trace-Id: 40396647090904155152 |
| X-Upstream-Latency: 2 |
| X-Proxy-Latency: 1 |
| X-Frame-Options: SAMEORIGIN |
| Content-Security-Policy: frame-ancestors none |
# 3. Rewrite 重写 Flag
rewrite 主要是用来重写 URL 或者跳转 URL 的指令。
| |
| |
| Syntax: rewrite regex replacement [flag]; |
| Default: -- |
| Context: server, location, if |
| |
| |
| last |
| break |
| redirect |
| permanent |
# **3.1 ** 测试代码准备
| [root@web01] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| rewrite /1.html /2.html; |
| rewrite /2.html /3.html; |
| } |
| |
| location /2.html { |
| rewrite /2.html /a.html; |
| } |
| |
| location /3.html { |
| rewrite /3.html /b.html; |
| } |
| } |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| |
| |
| [root@web01] |
| [root@web01] |
| [root@web01] |
| [root@web01] |
| [root@web01] |
| |
| |
| [root@web01 conf.d] |
| b.html |
# 3.2 Break 与 last
# 3.2.1 为代码添加 Break
| |
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| |
| |
| location / { |
| rewrite /1.html /2.html break; |
| rewrite /2.html /3.html; |
| } |
| |
| location /2.html { |
| rewrite /2.html /a.html; |
| } |
| |
| location /3.html { |
| rewrite /3.html /b.html; |
| } |
| } |
| |
| |
| [root@web01 conf.d] |
| 2.html |
# 3.2.2 为代码添加 last
| |
| |
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| rewrite /1.html /2.html last; |
| rewrite /2.html /3.html; |
| } |
| |
| location /2.html { |
| rewrite /2.html /a.html; |
| } |
| |
| location /3.html { |
| rewrite /3.html /b.html; |
| } |
| } |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| |
| [root@web01 conf.d] |
| a.html |
# 3.2.3 break 与 last 区别
- 当 rewrite 规则遇到 break 后,本 location {} 与其他 location {} 的所有规则都不执行。
- 当 rewrite 规则遇到 last 后,本 location {} 里后续规则不执行,但重写后的 url 会再次从头开始匹配所有 Location,哪个匹配执行哪个。
# 3.3 redirect 与 permanent
# 3.3.1 为代码添加 redirect
| [root@web01] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| rewrite /1.html /2.html redirect; |
| rewrite /2.html /3.html; |
| } |
| } |
# 3.3.2 为代码添加 permanent
| |
| [root@web01] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| rewrite /1.html /2.html permanent; |
| rewrite /2.html /3.html; |
| } |
| } |
# 3.3.3 redirect 与 permanent 区别
Flag | 跳转 | 状态码 | 排名情况 |
---|
redirect | 临时跳转 | 302 | 对旧网站无影响,新网站会有排名(不会) |
permanent | 永久跳转 | 301 | 新跳转网站有排名,旧网站排名会被清空(缓存下来) |
# 4.Rewrite 生产案例实践
# 4.1 Rewrite 跳转示例 1
| |
| |
| |
| url.hmallleasing.com --》hmallleasing.com/zh |
| url.hmallleasing.com --》hmallleasing.com/en |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| if ($http_accept_language ~* "zh-CN|zh") { |
| set $language zh; |
| } |
| |
| if ($http_accept_language ~* "en") { |
| set $language en; |
| } |
| |
| rewrite ^/$ /$language; |
| location / { |
| index index.html; |
| } |
| } |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
# 4.2 Rewrite 跳转示例 2
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| if ($http_user_agent ~* "android|iphone|ipad") { |
| rewrite ^/$ /m; |
| } |
| } |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
# 4.3 Rewrite 跳转示例 3
| |
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| if ($http_user_agent ~* "android|iphone|ipad") { |
| |
| rewrite ^/$ http://m.hmallleasing.com; |
| } |
| } |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| |
| |
| [root@web02 conf.d] |
| server { |
| listen 80; |
| server_name m.hmallleasing.com; |
| root /code/m; |
| |
| location / { |
| index index.html; |
| } |
| } |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
# 4.4 Rewrite 跳转示例 4
| |
| [root@web02 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| |
| return 302 https://$server_name$request_uri; |
| } |
| |
| server { |
| listen 443 ssl; |
| server_name url.hmallleasing.com; |
| ssl_prefer_server_ciphers on; |
| ssl_certificate /etc/nginx/sslkey/hmallleasing.com.pem; |
| ssl_certificate_key /etc/nginx/sslkey/hmallleasing.com.key; |
| |
| location / { |
| index index.html; |
| root /code; |
| } |
| } |
| |
| [root@web02 ~] |
| [root@web02 nginx] |
| [root@web02 nginx] |
| [root@web02 ssl] |
| -rw-r--r-- 1 root root 1675 Jun 14 22:01 hmallleasing.com.key |
| -rw-r--r-- 1 root root 4784 Jun 14 22:01 hmallleasing.com.pem |
| [root@web02 conf.d] |
# 4.5 Rewrite 跳转示例 5
| |
| [root@web01] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| rewrite ^(.*)$ /wh.html break; |
| |
| location / { |
| index index.html; |
| } |
| } |
| |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
# 4.6 Rewrite 跳转示例 6
| |
| [root@web02 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| index index.html; |
| } |
| |
| |
| error_page 404 403 502 = @tempdown; |
| location @tempdown { |
| rewrite ^(.*)$ /wh.html break; |
| } |
| } |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
# 4.7 Rewrite 跳转示例 7
| |
| [root@web02 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| |
| set $ip 0; |
| |
| |
| if ($remote_addr ~ "192.168.40.1|192.168.40.7") { |
| set $ip 1; |
| } |
| |
| |
| if ($ip = 0) { |
| rewrite ^(.*)$ /wh.html break; |
| } |
| |
| |
| location / { |
| index index.html; |
| } |
| } |
| |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
| |
| |
| [root@db01 ~] |
| wh..... |
| |
| |
| [root@web01 ~] |
| hello https |
# 4.8 Rewrite 跳转示例 8
| |
| |
| [[root@web02 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| index index.html; |
| } |
| |
| location /admin { |
| set $ip 0; |
| if ($remote_addr ~ "192.168.40.1|192.168.40.7") { |
| set $ip 1; |
| } |
| |
| if ($ip = 0){ |
| return 404; |
| |
| } |
| } |
| } |
| |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
| |
| |
| [root@web01 ~] |
| admin site |
| |
| |
| [root@db01 ~] |
| <html> |
| <head><title>404 Not Found</title></head> |
| <body> |
| <center><h1>404 Not Found</h1></center> |
| <hr><center>nginx/1.26.1</center> |
| </body> |
| </html> |
# 4.9 Rewrite 跳转示例 9
| |
| |
| |
| [root@web02 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| index index.html; |
| |
| if ( $http_host ~* (.*)\.(.*)\.(.*) ) { |
| set $domain $1; |
| } |
| |
| rewrite ^/(.*) http://demo:27610/$domain$request_uri redirect; |
| } |
| } |
| [root@web02 conf.d] |
| [root@web02 conf.d] |
| [root@web01 ~] |
| HTTP/1.1 302 Moved Temporarily |
| Server: nginx/1.26.1 |
| Date: Fri, 05 Sep 2025 14:26:44 GMT |
| Content-Type: text/html |
| Content-Length: 145 |
| Connection: keep-alive |
| Location: http://demo:27610/url/bbb |
# 4.10 Rewrite 跳转示例 10
现有两台服务器,想要实现 http://url.hmallleasing.com/index.php?r=sur/index/sid/613192/lang/zh-Hans 若访问资源为 /index.php?r=survey... 则跳转到 http://sur.hmallleasing.com/index.php?r=survey/index/sid/613192/lang/zh-Hans
请求的域名:http://url.hmallleasing.com/index.php?r=survey/index/sid/613192/lang/zh-Hans
替换后域名:http://sur.hmallleasing.com/index.php?r=survey/index/sid/613192/lang/zh-Hans
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| index index.html; |
| |
| location / { |
| if ($args ~* "r=survey") { |
| |
| rewrite ^/(.*) http://sur.hmallleasing.com$request_uri? redirect; |
| } |
| } |
| } |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| |
| |
| |
| [root@web01 conf.d] |
| HTTP/1.1 302 Moved Temporarily |
| Server: nginx/1.26.1 |
| Date: Sat, 06 Sep 2025 06:31:24 GMT |
| Content-Type: text/html |
| Content-Length: 145 |
| Connection: keep-alive |
| Location: http://sur.hmallleasing.com/index.php?r=survey/index/sid/613192/lang/zh-Hans |
# 4.11 Rewrite 跳转示例 11
需求:将用户请求 http://url.hmallleasing.net/?id=2,替换为 http://url.hmallleasing.net/id/2.html
- 1. 必须是请求 id? 判断用户请求的是 id 这个关键参数;
- 2. 提取整个 uri 中的两个字段, 将左边的做成一个变量,将右边的做成一个变量;
- 3. 如果来源为 id 成立的话,则执行 rewirte;
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| if ($args ~* "id") { |
| set $OK 1; |
| } |
| |
| if ($args ~* (.*)\=(.*)) { |
| set $id $1; |
| set $number $2; |
| } |
| |
| if ($OK = "1") { |
| |
| rewrite ^(.*)$ http://${server_name}/${id}/${number}.html? last; |
| } |
| } |
| } |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| |
| |
| [root@web01 conf.d] |
| HTTP/1.1 302 Moved Temporarily |
| Server: nginx/1.26.1 |
| Date: Sat, 06 Sep 2025 06:49:24 GMT |
| Content-Type: text/html |
| Content-Length: 145 |
| Connection: keep-alive |
| Location: http://url.hmallleasing.com/id/2.html |
# 4.12 禁止搜索引擎爬取站点
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name url.hmallleasing.com; |
| root /code; |
| |
| location / { |
| index index.html; |
| |
| if ($http_user_agent ~* "YisouSpider|YoudaoBot|tt") { |
| return 403; |
| } |
| } |
| |
| } |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
| |
| |
| [root@web01 conf.d] |
| HTTP/1.1 403 Forbidden |
| Server: nginx/1.26.1 |
| Date: Sat, 06 Sep 2025 06:59:32 GMT |
| Content-Type: text/html |
| Content-Length: 153 |
| Connection: keep-alive |
| |
| [root@web01 conf.d] |
| HTTP/1.1 200 OK |
| Server: nginx/1.26.1 |
| Date: Sat, 06 Sep 2025 06:59:32 GMT |
| Content-Type: text/html |
| Content-Length: 12 |
| Last-Modified: Sat, 06 Sep 2025 06:58:31 GMT |
| Connection: keep-alive |
| ETag: "68bbdb97-c" |
| Accept-Ranges: bytes |
| |
| [root@web01 conf.d] |
| HTTP/1.1 403 Forbidden |
| Server: nginx/1.26.1 |
| Date: Sat, 06 Sep 2025 06:59:32 GMT |
| Content-Type: text/html |
| Content-Length: 153 |
| Connection: keep-alive |
| |
| [root@web01 conf.d] |
| HTTP/1.1 200 OK |
| Server: nginx/1.26.1 |
| Date: Sat, 06 Sep 2025 06:59:34 GMT |
| Content-Type: text/html |
| Content-Length: 12 |
| Last-Modified: Sat, 06 Sep 2025 06:58:31 GMT |
| Connection: keep-alive |
| ETag: "68bbdb97-c" |
| Accept-Ranges: bytes |
# 4.13 禁止站点资源被盗用
防盗链,指的是防止资源被其他网站恶意盗用。如何避免网站资源被盗用:可以根据客户端请求所携带的 Referer 信息来验证请求的合法性,因为 Referer 会告诉服务器它是丛哪一个域名点击过来的;
基于 Referer 限制盗链:
- 优点:规则简单、配置和使用都很方便,
- 缺点:防盗链所依赖的 Referer 验证信息是可以伪造的,并非 100% 可靠,但基于 Referer 限制盗链的方式,可以限制绝大多数盗链情况。
# 4.13.1 环境准备
# 4.13.2 配置被盗链节点
| |
| [root@web02 ~] |
| server { |
| listen 80; |
| server_name image.hmallleasing.com; |
| root /code; |
| |
| location / { |
| index index.html; |
| } |
| } |
| |
| [root@web02 ~] |
| [root@web02 ~] |
| |
| |
| [root@web02 code] |
| -rw-r--r-- 1 root root 15817 Sep 6 15:38 /code/xld.jpg |
# 4.13.3 配置盗链节点
| |
| [root@web01 conf.d] |
| server { |
| listen 80; |
| server_name tou.hmallleasing.com; |
| |
| location / { |
| root /code; |
| index index.html; |
| } |
| } |
| |
| [root@web01 conf.d] |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <title>hmallleasing.com</title> |
| </head> |
| <img src="http://image.hmallleasing.com/xld.jpg"/> |
| </html> |
| |
| [root@web01 conf.d] |
| [root@web01 conf.d] |
使用浏览器能正常访问到偷链的后的图片资源
![2.jpg]()
# 4.13.4 防盗链配置语法
| |
| Syntax: valid_referers none | blocked | server_names | string ...; |
| Default: — |
| Context: server, location |
| |
| |
| |
| |
# 4.13.5 防盗链配置实践
配置所有来自 *.hmallleasing.com 都可以访问到 image.oldxu.net 站点的图片如果来源域名不在这个列表中,那么 $invalid_referer 变量值为 1,后续通过 if 判断,进行错误返回;
| [root@web02 code] |
| server { |
| listen 80; |
| server_name image.hmallleasing.com; |
| root /code; |
| |
| location / { |
| index index.html; |
| } |
| |
| location ~ .*\.(jpg|jpeg|gif|png)$ { |
| |
| valid_referers none blocked *.hmallleasing.net; |
| if ($invalid_referer) { |
| return 403; |
| |
| |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| [root@web02 code] |
| [root@web02 code] |
4.13.6 防盗链结果验证
![1.jpg]()