阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Nginx 开启 URL重写

154次阅读
没有评论

共计 3988 个字符,预计需要花费 10 分钟才能阅读完成。

本文目录:

1.1 URL 重写简介
1.2 if 指令
1.3 rewrite 指令
1.4 URL 重写和反向代理的区别

 

1.1 简介

url 重写由 ngx_http_rewrite_module 模块提供,默认会安装,但该模块功能的实现需要 pcre。URL 重写技术不仅要求掌握几个指令的语法、熟悉简单的正则表达式,还需要尽量熟悉 nginx 的各个变量的意义,熟悉的变量越多越好。大多数需要用到的变量都是 http_core 模块提供的,它们的意义参见官方手册http_core 内置变量

rewrite 模块主要有 break、return、set、rewrite 和 if 这 5 个指令。

  • break 的作用是完成当前的作用集,不再执行 rewrite 指令
  • return 返回状态码。可用的状态码有 204/301/302/303/307/308/400/402-406/408/410-411/413/416/500-504。return 三种语法:
    return code [text];
    return code URL;
    return URL;
    
  • set 用于定义变量。赋给变量的值可以是一个变量、文本及文本变量的组合(语法:set variable value;)
  • if 用于设定判断条件。格式为 if (condition) {}
  • rewrite 用于设定 URL 重写规则(语法:rewrite regex replacement [flag];)

 

1.2 if 指令

if 不支持嵌套,不支持 ”&&” 和 ”||” 多目运算符。语法为:

if (condition) {}

测试条件可以如下定义:

(1). 变量的比较可以使用 ”=” 和 ”!=” 运算符。
(2). 正则匹配可以使用 ”~” 和 ”~*”, 前者表示区分大小写的正则匹配,后者表示不区分大小写的匹配。
(3). 正则匹配可以在前面加上感叹号 ”!~” 和 ”!~*” 表示取反,即不匹配。
(4). “-f” 和 ”!-f” 判断文件是否存在。
(5). “-d” 和 ”!-d” 判断目录是否存在。
(6). “-e” 和 ”!-e” 判断文件或目录或软链接是否存在。
(7). “-x” 和 ”!-x” 判断文件是否可执行。

if 支持的正则表达式可以使用 $1 至 $9 来实现反向引用。

以下为几个示例:

# 当使用 IE 浏览器访问时,重定向到 /msie/ 目录下的对应文件
if ($http_user_agent ~ MSIE) {rewrite ^(.*)$ /msie/$1 break;
}

# 当 http 请求的方法为 POST,则直接返回 405 状态码,即 Method not Allowed
if ($request_method = POST) {return 405;
}

# 当请求的资源文件不存在,则直接退出当前匹配,并代理至本机,这种情况下由本机来提供服务,如提供错误页面
if (!-f $request_filename) {break;
    proxy_pass http://127.0.0.1;
}

# 当访问的是 linuxidc.com 下任意主机,则重定向到 www.linuxidc.com 主机下的对应目录
if ($http_host ~* "^(.*)\.linuxidc\.com$") {set $domain $1;
    rewrite ^(.*) http://www.linuxidc.com/$domain/ break;
}

上面最后一种URL 重写后的 URL 为一个新的主机名站点,但使用 URL 重写的效率比较低下,远不如直接为此站点独立定义一个虚拟主机。所以改写为:

server {listen 80;
    server_name .linuxidc.com;
    return 302 http://www.linuxidc.com/$request_uri;
}

server {listen 80;
    server_name www.linuxidc.com;
}

 

1.3 rewrite 指令

rewrite 可以写在 server 段、location 段和 if 段。语法:

rewrite regexp replacement [flag]

如果 replacement 部分以 ”http://” 或 ”https://” 或 ”$schema” 开头,则直接临时重定向,见下表中的 redirect 标记。

flag 是标记。有 4 种标记,它们的作用如下表。

flag 说明
last 停止处理当前上下文中的其他重写模块指令,并为重写后的 uri 再次进行上下文的匹配
break 和 break 指令一样,都是停止处理当前上下文中的其他重写模块指令
redirect 返回临时重定向状态码 302。当 replacement 部分不是以 ”http://” 或者 ”https://” 或者 ”$schema” 开头的时候使用,”$schema” 变量表示使用的是什么协议
permanent 返回永久重定向状态码 301

以上 flag 中,last 和 break 用来实现 URL 改写,此时浏览器中的地址不会改变,但实际上在服务器上访问的资源和路径已经改变了。redirect 和 permanent 用来实现 URL 跳转,浏览器中的地址会改变为跳转后的地址

在使用 proxy_pass 指令时要使用 break 标记。last 标记在本条 rewrite 规则执行完后,继续在当前上下文对重写后的地址发起匹配请求,而 break 则在本次匹配完成后停止再次匹配。例如下面的两条重写规则。

rewrite "^/bbs/(.*)/images/(.*)\.jpg$" www.linuxidc.com/bbs/$2/images/$1.jpg last;
rewrite "^/bbs/(.*)/images/(.*)\.jpg$" www.linuxidc.com/bbs/$2/images/$1.jpg break;

如果访问的是 www.linuxidc.com/bbs/a/images/b.jpg 则重写后为 www.linuxidc.com/bbs/b/images/a.jpg,但是重写后的地址仍然可以匹配到规则^/bbs/(.*)/images/(.*)\.jpg$,此时如果使用 last 标记,则会再次进行重写,最终导致 URL 重写循环,nginx 默认支持 10 次循环,然后返回 500 状态码。而如果使用 break 标记,则在重写完成后不会再次匹配重写。

例如,下面的重写示例将会使得任意以 linuxidc.com 结尾的访问重定向到 www.linuxidc.com。

server_name  www.linuxidc.com;
rewrite (.*).linuxidc.com www.linuxidc.com permanent;

下面的重写实例将使得 www.linuxidc.com/bbs/* 的访问都重定向到 www.linuxidc.com/forum/*。

server {listen 80;
    server_name www.linuxidc.com;
    location /{root /www/linuxidc/;
        index index.html;
        rewrite "/bbs/(.*)" "/forum/$1" last;
    }
}

 

1.4 URL 重写和反向代理的区别

URL 重写和反向代理都能将请求转发到其他主机上。但它们有很大的区别。

1.URL 重写可以实现一些反向代理不能实现的转发。
2.URL 重写可以实现浏览器地址改变。
3. 反向代理更多的配合 upstream 实现负载均衡。URL 重写无法直接通过转发实现负载均衡。
4. 还有很多其他的区别,无需关心它们的区别,当某种需求既可以 URL 重写实现,也可以反向代理实现,随便用一种方法即可。

下面关于 Nginx 的文章您也可能喜欢,不妨参考下:

Nginx 403 forbidden 的解决办法  http://www.linuxidc.com/Linux/2017-08/146084.htm

CentOS 7 下 Nginx 服务器的安装配置  http://www.linuxidc.com/Linux/2017-04/142986.htm

CentOS 上安装 Nginx 服务器实现虚拟主机和域名重定向  http://www.linuxidc.com/Linux/2017-04/142642.htm

CentOS 6.8 安装 LNMP 环境(Linux+Nginx+MySQL+PHP)http://www.linuxidc.com/Linux/2017-04/142880.htm

Linux 下安装 PHP 环境并配置 Nginx 支持 php-fpm 模块  http://www.linuxidc.com/Linux/2017-05/144333.htm

Nginx 服务的 SSL 认证和 htpasswd 认证  http://www.linuxidc.com/Linux/2017-04/142478.htm

Ubuntu 16.04 上启用加密安全的 Nginx Web 服务器  http://www.linuxidc.com/Linux/2017-07/145522.htm

Linux 中安装配置 Nginx 及参数详解  http://www.linuxidc.com/Linux/2017-05/143853.htm

Nginx 日志过滤 使用 ngx_log_if 不记录特定日志 http://www.linuxidc.com/Linux/2014-07/104686.htm

CentOS 7.2 下 Nginx+PHP+MySQL+Memcache 缓存服务器安装配置  http://www.linuxidc.com/Linux/2017-03/142168.htm

CentOS6.9 编译安装 Nginx1.4.7  http://www.linuxidc.com/Linux/2017-06/144473.htm

Nginx ��详细介绍:请点这里
Nginx 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-10/147766.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计3988字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中