详解Nginx中的Rewrite的重定向配置与实践

详解Nginx中的Rewrite的重定向配置与实践,第1张

详解Nginx中的Rewrite的重定向配置与实践

本文主要介绍Nginx中的重定向配置和重写实践。通过示例代码详细介绍,对大家的学习或工作有一定的参考价值。让我们跟着边肖学。

一:了解地址重写和地址转发的意义。

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

地址重写是为了标准化地址。例如,我们可以在地址栏中输入www.baidu.com。我们也可以进入www.baidu.cn。最后,它将被改写成www.baidu.com。浏览器的地址栏也会显示www.baidu.com。

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

因此,地址重写和地址转发有以下区别:

1.地址重写会改变浏览器中的地址,使其成为浏览器中最新重写的地址。而且地址转发不会改变浏览器的地址。
2。地址重写会产生两个请求,而地址转发只有一个请求。
3。地址转发通常发生在同一个站点项目中,但是地址被无限制地重写。[br/] 4。地址转发比地址重定向快。

II:理解重写指令的使用

此指令通过使用正则表达式来更改URI。可以同时有一个或多个指令。URL需要匹配并按顺序处理。

该指令可以在服务器块或位置块中配置,其基本语法结构如下:

rewriteregexreplacement[flag];

重写的含义:该指令是重写URL的指令。
regex的含义:用于匹配URIs的正则表达式。
replacement:用replacement替换regex定期匹配的内容。
flag:标志。

标志具有以下值:

  • 最后:该规则匹配完成后,继续向下匹配新的位置URI规则。(不常用)
  • Break:该规则匹配时终止,后续任何规则都不会匹配(不常用)。
  • 重定向:返回302临时重定向,浏览器地址会显示新的URL地址。
  • 永久:返回301永久重定向。浏览器地址将显示新的URL地址。
  • 例如,下面的例子:

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

    注意:
    rewrite是一个固定的关键字,表示启动了重写匹配规则。
    regex是/(。*).这是匹配完整域名和以下路径地址的正则表达式。
    替换为http://www.baidu.com/,,其中是正则表达式部分()中的内容。匹配成功时要跳转到的URL。
    标志是永久的,意思是“永久重定向”,即跳转到http://www.baidu.com/.的地址

    让我们制作一个简单的演示来模拟它:

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

    constKoa=require('koa'); constapp=newKoa(); constrouter=require('koa-router')(); //添加路由 router.get('/',ctx=>{ ctx.body='<h1>欢迎光临indexpage页面</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('serverisrunningathttp://localhost:3001'); });

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

    cd/usr/local/etc/nginx

    然后使用命令:sudoupen/usr/local/etc/nginx/nginx.conf-a'sublimetext'命令打开nginx.conf并对其进行如下配置:

    worker_processes1; events{ worker_connections1024; } http{ includemime.types; default_typeapplication/octet-stream; sendfileon; #tcp_nopushon; #keepalive_timeout0; keepalive_timeout65; #gzipon; server{ listen8081; server_namelocalhost; location/{ roothtml; indexindex.htmlindex.htm; } error_page500502503504/50x.html; location=/50x.html{ roothtml; } } server{ listen8088; server_namexxx.abc.com; location/{ proxy_passhttp://127.0.0.1:3001; rewrite^/(.*)http://www.baidu.compermanent; } } }

    如上面的代码所示,我的监控端口号是8088,然后server_name配置设置为xxx.abc.com。然后,当我们访问http://xxx.abc.com:8088/,时,我们将反向代理到对应于我们的http://127.0.0.1:3001下的节点的页面。反向代理完成后,我们将使用重写来重定向百度页面。以上配置完成后,我们需要重启nginx服务器;命令:

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

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

    III:理解if指令

    该指令用于支持条件判断,根据条件判断的结果选择nginx的不同配置。我们可以在服务器块或位置块中配置这条指令,它的语法结构是:

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

    条件是布尔值真/假的含义。

    可用于重写指令的全局变量如下:

    1.$args:这个变量在请求URL中存储请求指令。比如http://127.0.0.1:3001?arg1=value1&
    "arg2=value2&arg2=value2".
    2。$content_length:这个变量保存请求头中的Content-length字段。
    3。$content_type:这个变量保存请求头中的内容类型字段。[br/] 4。$document_root:当前请求的根路径存储在这个变量中。/br/] 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。$http_host:这个变量和$host唯一的区别就是端口号:比如xxx.abc.com:8080
    8。$http_user_agent:该变量存储客户端的代理信息。
    [h/]9。$http_cookie,存储客户端的cookie信息。
    10。$remote_addr客户端的地址存储在这个变量中。[br/][h/]11。$remote_port该变量存储客户端和服务器之间连接的端口号。[br/] 12。客户机的用户名存储在remote_user变量中。/br/]13。$request_body_file变量存储发送到后端服务器的本地文件资源的名称
    14。$request_method变量存储客户端的请求方法,比如‘GET’和‘POST’。[br/] 15。当前请求的资源文件的路径名存储在变量$request_filename中。[br/][h/]16。当前请求的URI与请求指令一起存储在$request_URI变量中。
    。$query_string与变量$args的含义相同。[br/]18。$scheme变量存储客户端请求的协议,如'http','https'等。[br/] 19。客户端请求协议的版本(如“HTTP/1.0”和“HTTP/1.1”)存储在server_protocol变量中。
    ...诸如此类。

    正则表达式的基本语法:

    1.匹配变量

    ~'表示匹配过程区分大小写。
    '~*'表示匹配过程不区分大小写。
    '!~'如果'~'匹配失败,则此条件为真。
    '!~*"如果'~*'匹配失败,则此条件为真。

    例如,如下所示:

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

    2.确定请求的文件是否存在。

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

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

    3.确定请求的目录是否存在。使用'-d'和'!-迪

    如果请求的目录存在,使用'-d'返回true。否则,返回false。
    使用'!-d',如果请求的目录不存在,但此请求的父目录存在,则返回true。如果父目录不存在,它将返回false...等等,其他一些语法就不介绍了。

    现在我们用if指令给nginx增加一些判断;例如,当我们访问http://xxx.abc.com:8080/home,if$host='XXX.ABC.com'时,我们会进行重定向跳转。nginx配置代码如下:

    server{ listen8088; server_namexxx.abc.com; location/{ proxy_passhttp://127.0.0.1:3001; if($host='xxx.abc.com'){ rewrite^/(.*)http://www.cnblogs.comredirect; } } }

    Nginx的配置如上。如果我们访问http://xxx.abc.com:8088,它将被重定向到http://www.cnblogs.com。

    比如更多的判断,比如用户代理用手机访问的话,直接跳转到某个页面,或者用if判断。例如,如下所示:

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

    四:了解防盗链和nginx配置

    什么是防盗链?盗链可以理解为偷图片链接,也就是说偷别人的图片,用在自己的服务器上,所以防盗链可以理解为防止别人偷我的图片。

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

    实现防盗链:利用http协议中请求头的Referer头字段判断当前访问的网页或文件的源地址。通过这个头字段的值,我们可以检测访问目标资源的源地址。如果目标源地址不是我们自己站内的URL,那么在这种情况下,我们采取防范措施,实现防盗链。但是,请注意,Referer头字段中的值是可以更改的。所以这种方法并不能完全防止防盗链。

    利用Nginx服务器的重写功能实现防盗链。

    NGX中有一个指令valid_Referers。此指令可用于获取referrer头字段中的值,并根据该值为Nginx全局变量$invalid_referer赋值。如果referer头中没有与valid_referers指令匹配的值,则将为$invalid_referrer变量赋值1。

    valid_referers指令的基本语法如下:

    valid_referersnone|blocked|server_names|string

    None:检测引用标头域的缺失。
    blocked:检测到Referer头字段的值被防火墙或代理服务器删除或伪装。那么在这种情况下,头字段的值不会以“http://”或“https://”开头。

    Server_names:设置一个或多个URL,并检查Referer头字段的值是否是URL之一。

    所以,如果我们有valid_referers指令和$invalid_referrer变量,就可以通过重写函数实现防盗链。
    这里我们介绍两种方案:一是根据请求资源的类型。第二:按要求目录。

    1.根据请求文件类型,防盗链的配置如下:

    server{ listen8080; server_namexxx.abc.com location~*^.+\.(gif|jpg|png|swf|flv|rar|zip)${ valid_referersnoneblockedwww.xxx.comwww.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指令,则说明不是本站的资源请求。

    位置~*。+\.(gif|jpg|png|swf|flv|rar|zip)$这个配置的意义是设置防盗链的文件类型。

    valid_referersnone屏蔽了www.xxx.comwww.yyy.com*.Baidu.com*.tabobao.com;可以理解为白名单,允许文件链接到域名白名单。如果请求的资源文件不是以这些域名开头,说明请求的资源文件不是这个域下的请求,可以判断是盗链。所以如果不是这个域下的请求,你会用Rewrite重定向到这张http://www.xxx.com/images/forbidden.jpg.的图片比如这张图片是X或者其他logo,然后其他网站就无法访问你的图片了。

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

    server{ listen8080; server_namexxx.abc.com location/file/{ root/server/file/; valid_referersnoneblockedwww.xxx.comwww.yyy.com*.baidu.com*.tabobao.com; if($invalid_referer){ rewrite^/http://www.xxx.com/images/forbidden.png; } } }

    这就是这篇关于Nginx中重定向配置和重写实践的文章。有关Nginx重写重定向的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!

    欢迎分享,转载请注明来源:内存溢出

    原文地址: http://outofmemory.cn/zz/774582.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-05-03
    下一篇 2022-05-03

    发表评论

    登录后才能评论

    评论列表(0条)

    保存