Nginx Rewrite技术

news2024/11/20 7:01:49
  • 一:理解地址重写 与 地址转发的含义。
  • 二:理解 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.com
  location ~* ^.+\.(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.com
  location /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.coloradmin.cn/o/1838165.html

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

相关文章

抖音短剧看剧系统是怎么做的?怎么样搭建上线运营?

前言&#xff1a; 当前热门短剧已深入大家的日常&#xff0c;针对一些好的短剧更是吸金无数。今天给大家介绍一下短剧这个项目整个运作模式。 一、一部短剧是怎么样呈现到观众眼前的&#xff1f; 首先影视作品公司拍摄剪辑好短剧 &#xff0c;弄好一切审核后&#xff0c;放到…

【Python】类和对象的深入解析

目录 前言 什么是类&#xff1f; 定义一个类 创建对象 访问和修改属性 方法 类的继承 多态 封装 特殊方法 属性装饰器 总结 前言 Python 是一种面向对象的编程语言&#xff0c;它允许程序员通过类和对象来组织和管理代码。面向对象编程&#xff08;OOP&#xff09…

【数据结构与算法】最小生成树

文章目录 最小生成树&#xff08;MST&#xff09;定义 构造最小生成树Prim算法Kruskal算法 最小生成树&#xff08;MST&#xff09; 连通图的生成树包含图的所有顶点&#xff0c;并且只含有尽可能少的边。对于生成树来说&#xff0c;若砍去它的一条边&#xff0c;则会使生成树…

Linux中的文本编辑器vi与vim

摘要&#xff1a; 本文将深入探讨VI和VIM编辑器的基本概念、特点、使用方法以及它们在Linux环境中的重要性。通过对这两款强大的文本编辑器的详细分析&#xff0c;读者将能够更全面地理解它们的功能&#xff0c;并掌握如何有效地使用它们进行日常的文本编辑和处理任务。 引言&…

智慧之选:Vatee万腾平台,引领未来的创新引擎

在数字化浪潮席卷全球的今天&#xff0c;我们身处一个信息爆炸、技术革新的时代。在这样的大背景下&#xff0c;选择一个能够引领我们走向未来的平台显得尤为重要。而Vatee万腾平台&#xff0c;正是这样一个不容错过的智慧之选。 Vatee万腾平台&#xff0c;作为一个集创新、科技…

yolov8图像分割训练

1.背景 最近在做一个AI项目&#xff0c;需要用到yolov8的实例分割功能来确定一个不规则区域&#xff0c;从而找出不规则区域的坐标完成大致定位&#xff0c;以前有用过yolov8的目标检测功能&#xff0c;实际上yolov8的分割功能和检测功能大同小异。本博客将仔细分享使用yolov8图…

【C++提高编程-10】----C++ STL常用拷贝和替换算法

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

Intelij IDEA中Mapper.xml无法构建到资源目录的问题

问题场景&#xff1a; 在尝试把原本在eclipse上的Java Web项目转移至Intelij idea上时&#xff0c;在配置文件均与eclipse一致的情况下出现了如下报错&#xff1a; org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.umbrella.crm_core.…

Ubuntu网络管理命令:route

安装Ubuntu桌面系统&#xff08;虚拟机&#xff09;_虚拟机安装ubuntu桌面版-CSDN博客 route命令与ifconfig命令都在net-tools软件包中&#xff0c;是一个传统的Linux路由管理命令。通过route命令可以显示和管理路由表。route命令的基本语法如下&#xff1a; route [options]…

尚硅谷爬虫学习第一天(3) 请求对象定制

#url的组成 #协议 http&#xff0c;https&#xff0c;一个安全&#xff0c;一个不安全。 #主机&#xff0c; 端口号 学过java 的肯定知道 沃日&#xff0c;以前面试运维的时候&#xff0c;问到主机地址&#xff0c;我懵逼了下&#xff0c;回了个8080 # 主机地址 80 # …

[Redis]持久化机制

众所周知&#xff0c;Redis是内存数据库&#xff0c;也就是把数据存在内存上&#xff0c;读写速度很快&#xff0c;但是&#xff0c;内存的数据容易丢失&#xff0c;为了数据的持久性&#xff0c;还得把数据存储到硬盘上 也就是说&#xff0c;内存有一份数据&#xff0c;硬盘也…

python是TIOBE编程语言排名第一的编程语言,它有什么优点?它的使用场景有哪些?用python打印数字1--100,用python打印九九乘法表怎么写?

Python是TIOBE编程语言排行榜排名第一的编程语言 。 python是一种解释性、交互式、面向对象的跨平台的语言。 python设计者及名称由来 Guido van Rossum 荷兰人---吉多范罗苏姆&#xff0c;是 Python 编程语言的最初设计者&#xff0c;在 Python 社区一直担当终身仁慈独裁者&…

【权威出版/投稿优惠】2024年水利水电与能源环境科学国际会议(WRHEES 2024)

2024 International Conference on Water Resources, Hydropower, Energy and Environmental Science 2024年水利水电与能源环境科学国际会议 【会议信息】 会议简称&#xff1a;WRHEES 2024 大会时间&#xff1a;点击查看 截稿时间&#xff1a;点击查看 大会地点&#xff1a;…

聊一聊大模型应用落地那些事

大模型并不神奇 很多人听到"大模型"这个词可能会觉得很神秘&#xff0c;其实&#xff0c;LLM 就是神经网络&#xff0c;只是很大的神经网络&#xff0c;相对传统神经网络&#xff0c;大就是它的特点。我们用一个压缩算法的简单例子来帮助理解这个巨大的神经网络。 …

.[nicetomeetyou@onionmail.org].faust深入剖析勒索病毒及防范策略

引言&#xff1a; 在数字化时代&#xff0c;网络安全问题日益凸显&#xff0c;其中勒索病毒无疑是近年来网络安全的重大威胁之一。勒索病毒以其独特的加密机制和恶意勒索行为&#xff0c;给个人和企业带来了巨大的经济损失和数据安全风险。本文将从勒索病毒的传播方式、攻击链、…

.net 6 api 修改URL为小写

我们创建的api项目&#xff0c;url是[Route(“[controller]”)]&#xff0c;类似这样子定义的。我们的controller命名是大写字母开头的&#xff0c;显示在url很明显不是很好看&#xff08;url不区分大小写&#xff09;。转换方式&#xff1a; var builder WebApplication.Crea…

SpringBoot整合阿里云短信服务

文章目录 1. 准备工作2. 添加依赖3. 配置阿里云短信服务4. 创建配置类5. 创建服务类6.自定义异常7.使用服务类发送短信8.测试短信 1. 准备工作 注册阿里云账号&#xff1a;首先确保你有一个阿里云账号&#xff0c;并且已经开通了短信服务。获取AccessKey ID和AccessKey Secret…

奇怪的缓存一致性问题

天猫国际用户Push中心承接了国际用户触达相关的需求&#xff0c;比如短信、端内消息投放等等&#xff0c;并存在较高的并发场景。 该系统此前发现了一个查询投放计划plan为null的异常情况&#xff0c;在初期排查时有些丈二和尚摸不着头脑&#xff0c;后面突然灵光乍现——原来是…

探索线性回归模型

目录 一 线性回归的理论基础 什么是线性回归? 线性回归的假设 最小二乘法 二 线性回归的数学推导 线性回归参数的推导 多元线性回归 三 线性回归的模型构建 数据准备 训练模型 模型评估 四 线性回归的代码实现 基本实现 多元线性回归 五 线性回归的应用场景 预…

pygame游戏开发

Pygame游戏开发 pygame简介 模块库请参考&#xff1a;pygame官方文档 pygame可以用作游戏开发&#xff0c;但在商业游戏中真正的开发工具却不是pygame。使用pygame开发游戏周期长。 安装pygame 在pycharm中安装第三方库pygame&#xff1a; 在计算机中安装pygame&#xf…