设为首页 收藏本站
查看: 1844|回复: 0

[经验分享] Nginx里的rewrite功能

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-3-14 09:16:07 | 显示全部楼层 |阅读模式
Rewrite是什么?

Nginx的rewrite是支持正则表达式的,在上一篇文章里简单有写了一点正则表达式的内容,Nginx在编译的时候,需要按装PCRE库,这个是先决条件。

Rewrite功能主要作用就是对URL的重写,即网站的跳转。比如说某个新闻网页已经从“西甲板块”转移到了“欧冠板块”,那么网页的网址肯定也会发生改变,如果还输入老的网址,肯定得到的结果就是404,这样对用户的体验很不好,觉得这个网站什么破玩意,网页昨天在今天就没。于是管理员就可以使用nginx实现跳转,来“润物细无声”的把用户引导到新的网页上。比如把已经拆除的网页,引导到“找失踪儿童”这种公益网页上,比如可以智能的识别用户的浏览器,当用户使用的是手机上网的时候,就把对应手机版的网页呈现给用户。

举个例子,如果用户使用的是苹果产品的浏览器,nginx想对其不同的浏览器提供不同的内容。那么在nginx.conf里就可以在server里加上这么一句:
if(http_user_agent ~ Safari){
    rewrite ^(.*)$ /Safari/$1 break;
}
可见nginx里的if语句与shell的if是不同的,nginx里的if没有then和else,而是“if A 那就B”的模式。
http_user_agent指的是用户的浏览器,Safari是苹果浏览器(MSIE是micosoft IE,Firefox就是火狐),中间的~表示区分大小写。nginx里非变量是没有“=”的,这一点要注意。
如果用户当前使用的浏览器是Safari,那么就要rewrite,^是开头,$是结尾,(.*)指的是任意内容,第二句话的意思是把任意内容都跳转到/Safari/目录下的第一个变量,这里的第一个变量其实就是用户输入的那个地址。
break是flag标志,一定要加上。

也就说,如果用户是在Safari浏览器下的地址栏里输入www.JQK123.com/index.html,浏览器会自动跳转到www.JQK123.com/Safari/index.html上。


再举一个例子,
if(! -f $request_filename){
    remrite ^/img/(.*)$ /site/$host/images/$1 last;
}
!代表“非”,-f同shell一样,是检查文件是否存在的,第一句话指的是if request_filename不存在的话。就启动rewrite,具体rewrite的方式是:只要是/img/这个文件里要求的文件不存在,那么就转到“/site/指定的IP地址/images/请求的网页”上,最后的last同样是flag标志。

什么是flag?
nginx里的flag主要有以下四种:
1)last:相当于Apache里的L标记,表示完成了rewrite,浏览器地址栏url地址不跳转;
2)break:本条匹配完成之后,终止匹配,不会再匹配后面的原则,浏览器地址栏url地址不跳转;
3)redirect:302临时重定向,浏览器地址栏会显示跳转后的url地址;
4)permanent:301永久重定向,浏览器地址栏会显示跳转后的url地址;

如果是直接跟在server或者location后面的编写rewrite规则,那么推荐使用last标记,如果不是,比如server是www.JQK123.com,location是/news/,那么就要使用break标记。


举个例子,如果“访问的是www.ioio.com/bbs/  则跳转到 www.ioio.com/data/,同时地址栏也显示跳转",这样只需要在server/location下写“rewrite ^/bbs/?$ /data/ permanent;"即可。百度贴吧里输入wow会直接跳转到“魔兽世界”吧就是这个道理。

再举个例子, www.abc.com 原有的域名商谈崩了,现在仅留下一个首页,那么所有来源地址是www.abc.com 的请求全部改成了www.test.net,显示跳转后的地址,现在要做如下更改:

server{
    listen 80;    #监听80端口
    servername www.test.com;     #新服务器是www.test.com

    index index.html;    #默认网页
    root /usr/local/nginx/html    #指定root目录
    if ($host ="www.abc.com"){   

       rewrite ^/(.*)$ http://www.test.net/$1 permanent; #显示新地址,告诉用户,已经搬家了

}
}
补充---$host:in this order of precedence: host name from the request line, or host name from the “Host” request header field, or the server name matching a request
直白的翻译一下:host变量的值按照如下优先级获得:
  • 请求行中的host.
  • 请求头中的Host头部.
  • 与一条请求匹配的server name.


要注意一点,如果server里设定了rewrite,但是下面的location对具体的域名又给出了具体的动作,那么会以location的动作优先。

rewrite的语法规则
rewrite是支持变量的,但是只有变量才能“=”,这个前面说过了,直接就是"变量 判断 某某“的模式,同时rewrite支持$1~$9的位置化参数。

~是区分大小写的匹配;
~*是不区分大小写的匹配;
!是取反,跟shell、python一样;
-f 是文件是否存在;
-d是目录是否存在;
-e是文件或者目录是否存在(一劳永逸);
-x是文件是否执行;

return指令
location ~ .*\.(sh|bash)?${
    return 403;
}
这句话指的是,如果访问当年server下的所有以sh or bash结尾的文件,都会返回一个403的页面。那个红色的\表示转义符,去掉了.的特殊意义。

我个人觉得return最牛掰的地方是用来测试,比如说想知道nginx下各个参数都是神马东西,就可使用return,比如下面这个例子:
1.jpg
2.jpg
3.jpg
然后去浏览器进行访问,
4.jpg

各个参数是什么,一幕了然。


类似智能DNS的用法---set
有些网站比较国际化,里面提供了多种语言的支持,比如中文、英文、日文、葡萄牙语、西班牙语等等。而且这些网站都有一个智能DNS解析:如果服务器检测到用户使用的是大陆的IP地址,会自动显示简体中文的网页页面,如果服务器检测到用户使用的是台湾/香港的IP地址来登陆网页,就会自动显示繁体中文的界面,如果服务器检测到用户使用的是美国的IP地址,就会自动显示英文办的网页。这网站比较明显的就是www.nba.com,大陆用户登录直接就跳转到http://china.nba.com/?gr=www


当然除此之外,还有一种情况,就是公司有两套网站,一个是专门给内部人看的样子,另一个是专门给外网用户看的样子。同样的原理,检测到访问网站的是ip地址是192.168开头或者是内网的地址,那么就会呈现内网办网页,如果不是那些ip地址就会呈现外网版网页,这样的情况如何实现呢?

if ($host ~* ^(.*?)\aaa.\.com$){    #$host指的是来源的ip,不区分大小写的匹配的aaa.com后缀

    set $var_tz '1';    #那么给var_tz这个变量指定为1
}
if ($host ~* ^192\.168\.1\.(.*?)$){    #道理同上,如果来源的ip是192.168.1开头的
     set $var_tz '1';    #变量也是1
}
if ($var_tz !~'1'){        #当变量不是1的时候
    rewrite ^/(.*)$ http://www1.aaa.com rediect;    #就跳转到www1.aaa.com

}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-190517-1-1.html 上篇帖子: nginx upstream模块 下篇帖子: nginx1.6.3源码安装,centos6系统下详解
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表