Nginx Rewrite技术

  • 一:理解地址重写 与 地址转发的含义。
  • 二:理解 Rewrite指令 使用
  • 三:理解if指令
  • 四:理解防盗链及nginx配置

  简介:Rewrite是Nginx服务器提供的一个重要的功能,它可以实现URL重定向功能。

一:理解地址重写 与 地址转发的含义。

地址重写地址转发是两个不同的概念。

地址重写 是为了实现地址的标准化,比如我们可以在地址栏中中输入 www.baidu.com. 我们也可以输入 www.baidu.cn. 最后都会被重写到 www.baidu.com 上。浏览器的地址栏也会显示www.baidu.com。

地址转发:它是指在网络数据传输过程中数据分组到达路由器或桥接器后,该设备通过检查分组地址并将数据转发到最近的局域网的过程。

因此地址重写和地址转发有以下不同点:

1. 地址重写会改变浏览器中的地址,使之变成重写成浏览器最新的地址。而地址转发他是不会改变浏览器的地址的。
2. 地址重写会产生两次请求,而地址转发只会有一次请求。
3. 地址转发一般发生在同一站点项目内部,而地址重写且不受限制。
4. 地址转发的速度比地址重定向快。

回到顶部

二:理解 Rewrite指令 使用

该指令是通过正则表达式的使用来改变URI。可以同时存在一个或多个指令。需要按照顺序依次对URL进行匹配和处理。

该指令可以在server块或location块中配置,其基本语法结构如下:

rewrite regex replacement [flag];

rewrite的含义:该指令是实现URL重写的指令。
regex的含义:用于匹配URI的正则表达式。
replacement:将regex正则匹配到的内容替换成 replacement。
flag: flag标记。

flag有如下值:

last: 本条规则匹配完成后,继续向下匹配新的location URI 规则。(不常用)
break: 本条规则匹配完成即终止,不再匹配后面的任何规则(不常用)。
redirect: 返回302临时重定向,浏览器地址会显示跳转新的URL地址。
permanent: 返回301永久重定向。浏览器地址会显示跳转新的URL地址。

比如如下列子:

rewrite ^/(.*) http://www.baidu.com/$1 permanent;

说明:
rewrite 为固定关键字,表示开始进行rewrite匹配规则。
regex 为 ^/(.*)。 这是一个正则表达式,匹配完整的域名和后面的路径地址。
replacement就是 http://www.baidu.com/1这块了,其中1这块了,其中1是取regex部分()里面的内容。如果匹配成功后跳转到的URL。
flag 就是 permanent,代表永久重定向的含义,即跳转到 http://www.baidu.com/$1 地址上。

下面我们来做个简单的demo来模拟下:

1. 在我们的测试项目下有个app.js. 代码如下:

复制代码

const Koa = require('koa');
const app = new Koa();const router = require('koa-router')();// 添加路由
router.get('/', ctx => {ctx.body = '<h1>欢迎光临index page 页面</h1>';
});router.get('/home', ctx => {ctx.body = '<h1>欢迎光临home页面</h1>';
});router.get('/404', ctx => {ctx.body = '<h1>404...</h1>'
});// 加载路由中间件
app.use(router.routes());app.listen(3001, () => {  console.log('server is running at http://localhost:3001');
});

然后在命令行中 运行 node app.js 后,运行,我们就可以在浏览器中 访问 http://localhost:3001 就可以访问到我们对应的页面了。但是现在我想把该node项目
部署到我本地的nginx服务器上。nginx安装请看我这篇文章 然后我想使用域名来访问我们的项目,因此我们需要在我们的nginx.conf中配置一下:

cd /usr/local/etc/nginx

然后使用命令:sudo open /usr/local/etc/nginx/nginx.conf -a 'sublime text' 命令打开 nginx.conf 配置如下:

worker_processes  1;events {worker_connections  1024;
}
http {include       mime.types;default_type  application/octet-stream;sendfile        on;#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;#gzip  on;server {listen       8081;server_name  localhost;location / {root   html;index  index.html index.htm;  }error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}server {listen 8088;server_name xxx.abc.com;location / {proxy_pass http://127.0.0.1:3001;rewrite ^/(.*) http://www.baidu.com permanent;}}
}

如上代码,我监听端口号是8088,然后server_name 配置设置为 xxx.abc.com, 然后当我们访问 http://xxx.abc.com:8088/的时候,会先反向代理到我们的http://127.0.0.1:3001下的node对应的页面上来,反向代理完成后,会使用 rewrite 重定向百度页面去了。如上配置完成后,我们需要重启下nginx服务器;使用命令:

然后当我们在浏览器访问 http://xxx.abc.com:8088/ 的时候,会执行如下图所示,它会先对 http://xxx.abc.com:8088/ 进行永久重定向(301), 然后会访问百度(307),临时重定向到百度页面来,最终加载百度页面的地址;如下演示所示:

但是如果我把 permanent 改成 redirect 的话,比如nginx配置:rewrite ^/(.*) http://www.baidu.com redirect; 后,它就会变成302临时重定向了。如下所示:

回到顶部

三:理解if指令

 该指令用来支持条件判断的,并且根据条件判断结果来选择不同的nginx的配置,我们可以在server块或location块中配置该指令,它的语法结构为:

if (condition) {// ....
}

condition 是布尔值 true/false的含义。

Rewrite 指令可用的全局变量如下:

1. $args: 该变量中存放了请求URL中的请求指令。比如 http://127.0.0.1:3001?arg1=value1&arg2=value2 中的
"arg1=value1&arg2=value2"。
2. $content_length: 该变量中存放了请求头中的Content-length字段。
3. $content_type: 该变量中存放了请求头中的 Content-type字段。
4. $document_root: 该变量中存放了针对当前请求的根路径。
5. $document_uri: 该变量中存放了请求的当前URI, 但是不包括请求指令。比如 http://xxx.abc.com/home/1?arg1=value1&
arg2=value2; 中的 "/home/1"
6. $host: 变量中存放了请求的URL中的主机部分字段,比如http://xxx.abc.com:8080/home中的 xxx.abc.com.
7. $http_host: 该变量与$host唯一区别带有端口号:比如上面的是 xxx.abc.com:8080
8. $http_user_agent: 变量中存放客户端的代理信息。
9. $http_cookie, 该变量中存放客户端的cookie信息。
10. $remote_addr 该变量中存放客户端的地址。
11. $remote_port 该变量中存放了客户端与服务器建立连接的端口号。
12. $remote_user 变量中存放客户端的用户名。
13. $request_body_file 变量中存放了发给后端服务器的本地文件资源的名称
14. $request_method 变量中存放了客户端的请求方式,比如 'GET'、'POST'等。
15. $request_filename 变量中存放了当前请求的资源文件的路径名。
16. $request_uri 变量中存放了当前请求的URI,并且带请求指令。
17. $query_string 和变量$args含义一样。
18. $scheme 变量中存放了客户端请求使用的协议,比如 'http', 'https'等。
19. $server_protocol 变量中存放了客户端请求协议的版本, 比如 'HTTP/1.0'、'HTTP/1.1' 等。
..... 等等

正则表达式的基本语法:

1. 对变量进行匹配

'~' 表示匹配过程中对大小写敏感。
'~*' 表示匹配过程中对大小写不敏感。
'!~' 如果 '~' 匹配失败时,那么该条件就为true。
'!~*' 如果 '~*' 匹配失败时,那么该条件就为true。

比如如下:

if ($http_user_agent ~ MSIE) {// 代码的含义:$http_user_agent值中是否含有 MSIE 字符串,如果包含为true,否则为false
}

2. 判断请求的文件是否存在

'-f' 如果请求的文件存在,那么该条件为true。
'!-f' 如果该文件的目录存在,该文件不存在,那么返回true。如果该文件和目录都不存在,则为false。
如果请求的目录不存在,请求的文件存在,也为false。

if (-f $request_filename) {// 判断请求的文件是否存在
}if (!-f $request_filename) {// 判断请求的文件是否不存在
}

3. 判断请求的目录是否存在使用 '-d' 和 '!-d'

使用 '-d',如果请求的目录存在,则返回true。否则返回false。
使用 '!-d', 如果请求的目录不存在,但是该请求的上级目录存在,则返回true。如果该上级目录不存在,则返回false.... 等等其他一些语法,不多介绍。

现在我们使用if指令来对nginx加一些判断;比如说我们访问http://xxx.abc.com:8080/home时候,如果$host = 'xxx.abc.com' 的时候,就做重定向跳转,nginx配置代码如下:

server {listen 8088;server_name xxx.abc.com;location / {proxy_pass http://127.0.0.1:3001;if ($host = 'xxx.abc.com') {rewrite ^/(.*) http://www.cnblogs.com redirect;}}
}

nginx 如上配置,如果我们访问 http://xxx.abc.com:8088 的时候,它就会重定向到 http://www.cnblogs.com 来了。

比如更多的判断,比如如果用户代理是手机访问的话,直接跳转到某个页面去,也可以使用if判断。比如如下:

if ( $http_user_agent ~* "(Android)|(iPhone)|(Mobile)|(WAP)|(UCWEB)" ){rewrite ^/$  http://www.cnblogs.com  permanent;
}

回到顶部

四:理解防盗链及nginx配置

什么是防盗链?盗链可以理解盗图链接,也就是说把别人的图片偷过来用在自己的服务器上,那么防盗链可以理解为防止其他人把我的图片盗取过去。

防盗链的实现原理:客户端向服务器端请求资源时,为了减少网络带宽,提高响应时间,服务器一般不会一次将所有资源完整地传回客户端。比如请求一个网页时,首先会传回该网页的文本内容,当客户端浏览器在解析文本的过程中发现有图片存在时,会再次向服务器发起对该图片资源的请求,服务器将存储的图片资源再发送给客户端。但是如果这个图片是链接到其他站点的服务器上去了呢,比如在我项目中,我引用了的是淘宝中的一张图片的话,那么当我们网站重新加载的时候,就会请求淘宝的服务器,那么这就很有可能造成淘宝服务器负担。因此这个就是盗链行为。因此我们要实现防盗链。

实现防盗链:使用http协议中请求头部的Referer头域来判断当前访问的网页或文件的源地址。通过该头域的值,我们可以检测访问目标资源的源地址。如果目标源地址不是我们自己站内的URL的话,那么这种情况下,我们采取阻止措施,实现防盗链。但是注意的是:Referer头域中的值是可以被更改的。因此该方法也不能完全安全阻止防盗链。

使用Nginx服务器的Rewrite功能实现防盗链。

Nginx中有一个指令 valid_referers. 该指令可以用来获取 Referer 头域中的值,并且根据该值的情况给 Nginx全局变量 invalidreferer赋值。如果Referer头域中没有符合validreferers指令的值的话,𝑖𝑛𝑣𝑎𝑙𝑖𝑑𝑟𝑒𝑓𝑒𝑟𝑒𝑟赋值。如果𝑅𝑒𝑓𝑒𝑟𝑒𝑟头域中没有符合𝑣𝑎𝑙𝑖𝑑𝑟𝑒𝑓𝑒𝑟𝑒𝑟𝑠指令的值的话,invalid_referer变量将会赋值为1. valid_referers 指令基本语法如下:

valid_referers  none | blocked | server_names | string

none: 检测Referer头域不存在的情况。
blocked: 检测Referer头域的值被防火墙或者代理服务器删除或伪装的情况。那么在这种情况下,该头域的值不以"http://" 或 "https://" 开头。

server_names: 设置一个或多个URL,检测Referer头域的值是否是URL中的某个。

因此我们有了 valid_referers指令和$invalid_referer变量的话,我们就可以通过 Rewrite功能来实现防盗链。
下面我们介绍两种方案:第一:根据请求资源的类型。第二:根据请求目录。

1. 根据请求文件类型实现防盗链配置实列如下:

server {listen 8080;server_name xxx.abc.comlocation ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com  *.tabobao.com;if ($invalid_referer) {rewrite ^/ http://www.xxx.com/images/forbidden.png;}}
}

如上基本配置,当有网络连接对以 gif、jpg、png为后缀的图片资源时候、当有以swf、flv为后缀的媒体资源时、或以 rar、zip为后缀的压缩资源发起请求时,如果检测到Referer头域中没有符合 valid_referers指令的话,那么说明不是本站的资源请求。

location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ 该配置的含义是 设置防盗链的文件类型。

valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com *.tabobao.com; 可以理解为白名单,允许文件链出的域名白名单,如果请求的资源文件不是以这些域名开头的话,就说明请求的资源文件不是该域下的请求,因此可以判断它是盗链。因此如果不是该域下的请求,就会使用 Rewrite进行重定向到 http://www.xxx.com/images/forbidden.png 这个图片,比如这张图片是一个x或其他的标识,然后其他的网站就访问不了你这个图片哦。

2. 根据请求目录实现防盗链的配置实列如下:

复制代码

server {listen 8080;server_name xxx.abc.comlocation /file/ {root /server/file/;valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com  *.tabobao.com;if ($invalid_referer) {rewrite ^/ http://www.xxx.com/images/forbidden.png;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/30956.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库异常恢复2-备份文件恢复(快速恢复的手动启动方式)

(四) 备份文件备份恢复的概念 本次所说的数据恢复有异于数据的导入导出 1. 备份工具 gbase8s数据库提供了两种工具进行完成系统物理备份、逻辑日志备份和系统恢复&#xff1a;ontape和onbar ontape&#xff1a;提供了基本的系统物理备份、日志备份和恢复能力&#xff0c;其…

C++基础知识——命名空间

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan. 文章目录 1、什么是命名空间2、命名空间的作用3、如何定义命名…

js实现canvas截图功能

关键代码 使用canvas的导出功能和drawImage函数 class CropShape{cropShape(shape){let {x,y,w,h} shapeconsole.log(x,y,w,h)const roiCanvas document.createElement(canvas);document.getElementById(app).append(roiCanvas)const roiCtx roiCanvas.getContext(2d);roi…

贝叶斯优化、高斯过程相关概念总结

目录 贝叶斯优化 高斯过程 采集函数 贝叶斯优化 贝叶斯优化 &#xff5c; 黑盒优化全局最优方法 &#xff5c; Bayesian Optimization_哔哩哔哩_bilibili 贝叶斯优化用于解决寻找某个函数的最大值/最小值&#xff0c;在自变量维度比较小时(<20)表现的非常好。 适用…

《计算机英语》Unit1 计算机概述

期末试卷组成 1、选择20道 2、判断20道 3、词汇翻译&#xff08;单词词组&#xff0c;参照课后习题&#xff09; 4、翻译2道&#xff08;一道原题&#xff0c;参照作业&#xff09; Unit One Computer Overview 单元1 计算机概述 algorithm n. 算法 operate …

byte[]转MultipartFile、byte[]转File一次看个够

目录 需求背景 当你需要将byte[]、MultipartFile、File实现互转时&#xff0c;无外乎以下场景&#xff1a; 保存第三方接口返回二进制流前/后端文件流上传微服务间调用文件格式转换 正如你所需要的&#xff0c;通过搜索引擎筛选到我的本篇文章是因为你在开发中需要将byte[]转…

k8s学习笔记(一)

configMap 一般用来存储配置信息 创建configMap 从文件中获取信息创建&#xff1a;kubectl create configmap my-config --from-file/tmp/k8s/user.txt 直接指定信息&#xff1a; kubectl create configmap my-config01 --from-literalkey1config1 --from-literalkey2confi…

深度学习之计算机视觉

神经网络简介 全连接层和卷积层的根本区别在于权重在中间层中彼此连接的方式。图5.1描述了全连接层或线性层是如何工作的。 在计算机视觉中使用线性层或全连接层的最大挑战之一是它们丢失了所有空间信息&#xff0c;并且就全连接层使用的权重数量而言复杂度太高。例如&#xf…

鸿蒙Harmony实战—通过登录Demo了解ArkTS

ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性&#xff0c;是TS的超集。 ArkTS在TS的基础上主要扩展了如下能力&#xff1a; 基本语法&#xff1a;ArkTS定义…

最新版Cisco Packet Tracer思科模拟器Windows版本64位下载

Cisco Packet Tracer是思科公司推出的一款网络仿真工具&#xff0c;主要用于网络教学、培训和实验。它提供了一个真实的网络环境模拟平台&#xff0c;让用户可以设计、构建和调试网络&#xff0c;以及进行实时互动&#xff0c;从而帮助用户理解和实践网络技术。 通过 Cisco Pa…

Unity和UE免费领恐怖书本头怪兽角色模型恐怖或奇幻游戏monster适合FPS类型PBR202406202143

Unity和UE免费领恐怖书本头怪兽角色模型恐怖或奇幻游戏monster适合FPS类型PBR202406202143 Unity恐怖书本头怪兽角色模型&#xff1a;https://prf.hn/l/zpBqgVl UE恐怖书本头怪兽角色模型&#xff1a;https://prf.hn/l/4PzY1Qy 作者其他资产&#xff1a;https://prf.hn/l/0…

Fastjson漏洞之CVE-2022-25845

前言&#xff1a; 针对Fastjson之前已经介绍了&#xff0c;这里就不再重复了&#xff0c;漏洞CVE-2017-18349只能用来攻击>1.2.24版本的&#xff0c;CVE-2022-25845属于CVE-2017-18349的升级版&#xff0c;但是目前仅影响到1.2.83以下版本。CVE-2022-25845本质上是绕过了名…

SpringBoot | 实现邮件发送

运行环境&#xff1a; IntelliJ IDEA 2022.2.5 (Ultimate Edition) (注意&#xff1a;idea必须在2021版本以上&#xff09;JDK17 项目目录&#xff1a; 该项目分为pojo,service,controller,utils四个部分&#xff0c; 在pojo层里面写实体内容&#xff08;发邮件需要的发件人邮…

【etcd】etcd单机安装及简单操作

https://blog.csdn.net/Mr_XiMu/article/details/125026635 https://blog.csdn.net/m0_73192864/article/details/136509244 etcd在生产环境中一般为集群方式部署 etcd使用的2个默认端口号&#xff1a;2379和2380 2379&#xff1a;用于客户端通信(类似于sqlserver的1433&#x…

vscode卡顿问题处理(vue-official插件)

vue官方扩展由volar升级为vue-official&#xff0c;部分人的ide会变得非常卡顿&#xff0c;这是由于vscode本身一些问题导致&#xff0c;如下图作者解释&#xff1a; 解决方式&#xff1a; 通过禁用Hybrid模式&#xff0c;不使用tsserver来接管语言支持&#xff0c;卡顿会缓解…

CSS文本超限后使用省略号代替

方案一&#xff1a; 只显示一行&#xff0c;超限后使用省略号代替 .detail {overflow: hidden;text-overflow: ellipsis;white-space: nowrap; }方案二&#xff1a; 显示多行&#xff0c;到最后一行还没有显示完&#xff0c;则最后一行多出来的部分使用省略号代替。 .detai…

Vulhub——Log4j、solr

文章目录 一、Log4j1.1 Apache Log4j2 lookup JNDI 注入漏洞&#xff08;CVE-2021-44228&#xff09;1.2 Apache Log4j Server 反序列化命令执行漏洞&#xff08;CVE-2017-5645&#xff09; 二、Solr2.1 Apache Solr 远程命令执行漏洞&#xff08;CVE-2017-12629&#xff09;2.…

异步任务使用场景与实践

异步任务使用场景 根据同步/异步方式划分场景&#xff0c;各场景下常用的技术方案如下&#xff1a; 方式实现特点缺点同步HTTP RPC Cache etc.指标&#xff1a;RT、QPS、TPS、缓存命中率 等&#xff1b; 关注&#xff08;准&#xff09;实时数据&#xff0c;用户可交互1. 处…

javascript--类型检测 type of 和 instanceof

类型判断 1、typeof2、instanceof**instanceof 的原理** 3、constructor 1、typeof typeof在检测null、object、array、data的结果中都是object&#xff0c;所以无法用来区分这几个类型的区别。 <script>let a ["123",123,false,true,Symbol(1),new Date(),n…

ubuntu18.04 安装HBA

HBA是一个激光点云层级式的全局优化的程序&#xff0c;他的论文题目是&#xff1a;HBA: A Globally Consistent and Efficient Large-Scale LiDAR Mapping Module&#xff0c;对应的github地址是&#xff1a;HKU-Mars-Lab GitHub 学习本博客&#xff0c;可以学到gtsam安装&am…