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

[经验分享] nginx rewrite模块探究与实验

[复制链接]

尚未签到

发表于 2018-11-15 06:15:43 | 显示全部楼层 |阅读模式
  关于nginx中的rewrite,之前的理解总感觉有些不精确。比如以下问题,经过rewrite之后:
  什么情况会返回200?
  什么情况会返回301/302?
  什么情况浏览器里的url不变?
  什么情况浏览器里的url会变?
  什么情况匹配一次就不再匹配之后的规则或location?
  什么情况匹配到一条规则后,会以rewrite之后的url再到server段走一遍
  如果读者能理解清楚以上问题,则说明对nginx的rewrite整体上已经有了全面的认识。
  接下来我们针对以上问题,来通过试验逐一解答
  实验环境:nginx 1.8
  网站根目录:nginx/html
  注:在http段或者server段添加rewrite_log on;并且设置error_log为notice级别,可以在error og里捕捉到rewrite的过程
  一、先实验一个最简单的:http://172.16.25.162/ljk.html。该文件不在在html下,而在在html/wordpress下
  server {
  listen        80;
  server_name  localhost;
  rewrite_log on;
  location / {
  root   /usr/local/nginx/html;
  index  index.shtml index.php index.html;
  if (!-e $request_filename) {
  rewrite ^/(.+\..+)$ /wordpress/$1;
  }
  }
  观察nginx访问日志和错误日志
  access_log:
  "GET /ljk.html HTTP/1.1" 200
  error_log:
  *98 "^/(.+\..+)$" matches "/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html
  *98 rewritten data: "/wordpress/ljk.html", args: "", client:172.16.25.3, server: localhost, request: "GET /ljk.html
  浏览器里的url没有改变,状态码返回200
DSC0000.jpg

  由此可见,如此配置实现了一个最简单的内部跳转。
  二、再进一步,看一个两级的rewrite。将html/wordpress/下的ljk.html移到html/ljk/下,并且在location /wordpress 下配置重写规则
  location / {
  root   /usr/local/nginx/html;
  index  index.shtml index.php index.html;
  if (!-e $request_filename) {
  rewrite ^/(.+\..+)$ /wordpress/$1;
  }
  }
  location /wordpress  {
  if (!-e $request_filename) {
  rewrite ^/wordpress/(.+\..+)$ /ljk/$1;
  }
  }
  access_log:
  "GET /ljk.html HTTP/1.1" 200
  error_log:可以看到两次匹配与重写的过程
  *99 "^/(.+\..+)$" matches "/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html
  *99 rewritten data: "/wordpress/ljk.html", args: "", client:172.16.25.3, server: localhost, request: "GET /ljk.html
  *99 "^/wordpress/(.+\..+)$" matches "/wordpress/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html
  *99 rewritten data: "/ljk/ljk.html", args: "", client: 172.16.25.3, server: localhost, request: "GET /ljk.html
  浏览器url依然不变
DSC0001.jpg

  以上两个实验对用户透明,用户通过返回码或者地址栏url均不可感知rewrite的存在,可以看做‘内部重定向’;那么什么时候会产生‘外部重定向’呢,现在先试试Permanent、redirect两个标志
  三、重写规则后加上 permanent 标志
  location / {
  root   /usr/local/nginx/html;
  index  index.shtml index.php index.html;
  if (!-e $request_filename) {
  rewrite ^/(.+\..+)$ /wordpress/$1 permanent;
  }
  }
  访问http://172.16.25.162/ljk.html
  access_log:
  GET /ljk.html HTTP/1.1" 301     返回301
  GET /wordpress/ljk.html HTTP/1.1" 200
  注意此处产生了两个请求
  error_log:
  *107 "^/(.+\..+)$" matches "/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html
  *107 rewritten redirect: "/wordpress/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html
  浏览器地址栏变成了rewrite后的url
DSC0002.jpg

  四、重写规则后加上 redirect 标志
  location / {
  root   /usr/local/nginx/html;
  index  index.shtml index.php index.html;
  if (!-e $request_filename) {
  rewrite ^/(.+\..+)$ /wordpress/$1 redirect;
  }
  access_log:    两个请求
  "GET /ljk.html?sds HTTP/1.1" 302    临时重定向302
  "GET /wordpress/ljk.html HTTP/1.1" 200
  error_log:
  *108 "^/(.+\..+)$" matches "/ljk.html", client: 172.16.25.3, server: localhost, request: "GET /ljk.html
  *108 rewritten redirect: "/wordpress/ljk.html?sds", client: 172.16.25.3, server: localhost, request: "GET /ljk.ht         ml?sds
  浏览器地址栏变成了rewrite后的url
DSC0003.jpg

  由三四得出结论:Permanent、redirect两个标志控制是否将重过程在用户端体现出来(即将重写后的url显示在客户端)同时返回301 or 302。
  然后再试试last和break两个标志(需要两层及以上跳转来测试)
  按照网上较为普遍的说法:
  假如一个location里有多条rewrite规则,都是不在该location继续往下匹配,但是
  last: 匹配完该条语句后得到的url,重新到server标签下走一遍
  break:到此为止(直接以重写后的url在服务器寻找资源)
  实验环境:删除html/wordpress下的ljk.html,将ljk.html放置在html/ljk/ljk.html,然后在server标签下配置location /wordpress 的rewrite规则
  五、先来看下两次rewrite 规则不加标志的情况
  location / {
  root   /usr/local/nginx/html;
  index  index.shtml index.php index.html;
  if (!-e $request_filename) {
  rewrite ^/(.+\..+)$ /wordpress/$1;
  }
  }
  location /wordpress  {
  if (!-e $request_filename) {
  rewrite ^/wordpress/(.+\..+)$ /ljk/$1;
  }
  }
  access_log:
  GET /ljk.html HTTP/1.1" 200
  error_log:    经历两次匹配和重写
  *111 "^/(.+\..+)$" matches "/ljk.html",
  *111 rewritten data: "/wordpress/ljk.html", args: "",
  *111 "^/wordpress/(.+\..+)$" matches "/wordpress/ljk.html",
  *111 rewritten data: "/ljk/ljk.html", args: "",
  浏览器地址栏url不变
  六、实验break标志
  location / {
  root   /usr/local/nginx/html;
  index  index.shtml index.php index.html;
  if (!-e $request_filename) {
  rewrite ^/(.+\..+)$ /wordpress/$1 break;
  }
  }
  location /wordpress  {
  if (!-e $request_filename) {
  rewrite ^/wordpress/(.+\..+)$ /ljk/$1;
  }
  }
  access_log:
  GET /ljk.html HTTP/1.1" 404
  error_log:
  *112 "^/(.+\..+)$" matches "/ljk.html",
  *112 rewritten data: "/wordpress/ljk.html", args: "",
  *112 open() "/usr/local/nginx/html/wordpress/ljk.html" failed (2: No such file or directory),
  加了break,所以在重写成‘wordpress/ljk.html’就没有再走到location /wordpress
  七、实验last标志
  location / {
  root   /usr/local/nginx/html;
  index  index.shtml index.php index.html;
  if (!-e $request_filename) {
  rewrite ^/(.+\..+)$ /wordpress/$1 last;
  }
  }
  location /wordpress  {
  if (!-e $request_filename) {
  rewrite ^/wordpress/(.+\..+)$ /ljk/$1;
  }
  }
  访问http://172.16.25.162/ljk.html
  access_log:
  GET /ljk.html HTTP/1.1" 200
  error_log:
  *113 "^/(.+\..+)$" matches "/ljk.html",
  *113 rewritten data: "/wordpress/ljk.html", args: "",
  *113 "^/wordpress/(.+\..+)$" matches "/wordpress/ljk.html",
  *113 rewritten data: "/ljk/ljk.html", args: "",
  由五六七可得出结论:
  加break标志时,url一旦找到匹配额规则,就会停止继续匹配并以该rewrite后额url去服务器请求资源;
  加last标志或者不加任何标志,其‘过程’和‘结果’一致,会以rewrite后的url再重新到server段下走一遍配置。
  并且这两个标志都不会改变浏览器地址栏的url,且返回码亦为200或404等(即对用户透明)
  八、涉及到域名重定向的实验
  server {
  listen        80;
  server_name  localhost;
  rewrite_log on;
  rewrite ^(.*)$ http://www.baidu.com;
  }
  若rewrite规则后不加标志或者加redircet标志,都会返回“GET / HTTP/1.1" 302”临时重定向
  当rewrite规则后加permanent 标志,会返回“GET / HTTP/1.1" 301”永久重定向
  希望这篇文章能对理解nginx的rewrite有一些帮助!


运维网声明 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-635095-1-1.html 上篇帖子: ubuntu nginx bugzilla的配置以及一些错误 下篇帖子: Nginx学习日记第五篇 -- upstream及fastcgi
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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