Nginx Rewrite

发布时间 2023-12-11 21:41:39作者: citywalk

Nginx  Rewrite

LOCATION

常用NGINX 正则表达式

^ :匹配输入字符串的起始位置
$ :匹配输入字符串的结束位置
* :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+ :匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“olll”,但不能匹配“o”
? :匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效于”{0,1}”
. :匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式
\ :将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
\d :匹配纯数字[0-9]   \s :空白符    \w :任意单词字符包括下划线[A-Za-z0-9_]
{n} :重复 n 次
{n,} :重复 n 次或更多次
{n,m} :重复 n 到 m 次
[] :定义匹配的字符范围
[c] :匹配单个字符 c
[a-z] :匹配 a-z 小写字母的任意一个
[a-zA-Z0-9] :匹配所有大小写字母或数字
() :表达式的开始和结束位置
| :或运算符

 

从功能看 rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于 rewrite 是在同一域名内更改获取资源的路径,而 location 是对一类路径做控制访问或反向代理,还可以proxy_pass 到其他机器。

rewrite 对访问的域名或者域名内的URL路径地址重写
location 对访问的路径做访问控制或者代理转发

 

location 三类

精准匹配:location = / {...}
一般匹配:location / {...}
正则匹配:location ~ / {...}

location 常用的匹配规则

= :进行普通字符精确匹配,也就是完全匹配。
^~ :表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其它 正则匹配location。
~ :区分大小写的匹配。
~* :不区分大小写的匹配。
!~ :区分大小写的匹配取非。
!~* :不区分大小写的匹配取非。

location 优先级

首先精确匹配 =     #优先级最高
其次前缀匹配 ^~
其次是按文件中顺序的正则匹配 ~或~*
然后匹配不带任何修饰符的一般前缀匹配
最后是交给 / 通用匹配


(location = 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分前缀路径) > (location /)

 

 

location 匹配

首先看 优先级:精确= > 前缀^~ > 正则~,~* > 一般 > 通用/

rowrite 先对用户的URL访问路径或者域名进行重写,在重新发起访问请求 (重定向请求)

匹配机制

优先级:精准匹配 = > 前缀匹配 ^~ > 正则匹配 ~,~* ,!~ ,!~* >一般前缀匹配 /xxxxx > 通用匹配 /

在没有精准匹配的时候,先看所有前缀匹配的长度,取最长匹配的location;如果最长的前缀匹配带有^~ 的前缀匹配则不看其他的正则匹配,直接使用^~ 的location匹配用户的访问路径并跳转页面;如果最长的前缀匹配是不带^~ 的,则会继续看其他的正则匹配。

前缀匹配看长度,最长的优先匹配;正则匹配看上下顺序,根据配置文件的配置 由上往下依次匹配,匹配到即停止

 

三个匹配规则定义

#第一个必选规则
直接匹配网站根目录首页,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。
可以是一个静态首页,也可以直接转发给后端应用服务器
location = /index.html {
    root   html;
    index  index.html index.htm;
}

#第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
    root /webroot/;
}

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}

#第三个规则就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器
非静态文件请求就默认是动态请求
location / {
    proxy_pass http://tomcat_server;
}

 

NGINX REWRITE

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。 比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。

rewrite只能放在server{},location{},if{}中,并且默认只能对域名后边的除去传递的参数外的字符串起作用, 例如 http://www.kgc.com/abc/bbs/index.php?a=1&b=2 只对/abc/bbs/index.php重写。

全局变量

Rewrite全局变量是什么?
$remoteaddr//获取客户端ip
$binary_remoteaddr//客户端ip(二进制)
$remoteport//客户端port,如:50472
$remoteuser//已经经过Auth Basic Module验证的用户名$host //请求主机头字段,否则为服务器名称,如:blog.sakmon.com
$request //用户请求信息,如:GET ?a=1&b=2HTTP/1.1$request filename //当前请求的文件的路径名,由root或alias和URI request组合而成,如:/2013/81.ht$status//请求的响应状态码,如:200
$body_bytessent // 应时送出的body字节数数量。即使连接中断,这个数据也是精确的,如:40$content length //等于请求行的“Content Length”的值$content_type//等于请求行的“Content_Type”的值
$httpreferer//引用地址
$http user agent //客户端agent信息,如: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36(KH$args //与$query_string相同 等于当中URL的参数(GET),如a=1&b=2$document uri //与Suri相同 这个变量指当前的请求URI,不包括任何参数(见$args)如:/2013/81.html$documentroot//针对当前请求的根路径设置值$hostname//姐:centos53.localdomain
$httpcookie//客户端cookie信息
$cookieCOOKIE//cookieCOOKIE变量的值$is_args//如果有$args参数,这个变量等于”?”,否则等于”",空值,如?$limit rate //这个变量可以限制连接速率,0表示不限速$query string //与args相同 等于当中URL的参数(GET),如a=1&b=2$request_body //记录POST过来的数据信息$request body_file //客户端请求主体信息的临时文件名$request method //客户端请求的动作,通常为GET或POST,如: GET$request uri //包含请求参数的原始URI,不包含主机名,如: /2013/81.html?a=1&b=2$scheme //HTTP方法(如http,https),如: http$uri //这个变量指当前的请求URI,不包括任何参数(见$args) 如:/2013/81.html$request_completion //如果请求结束,设置为OK,当请求未结束或如果该请求不是请求链串的最后一个时,为$server_protocol //请求使用的协议,通常是HTTP/1.0或HTTP/1.1,如: HTTP/1.1$server addr //服务器IP地址,在完成一次系统调用后可以确定这个值$server name //服务器名称,如: blog.sakmon.com$server port //请求到达服务器的端口号,如:80

 

语法格式:rewrite <regex> <replacement> [flag]; regex :表示正则匹配规则。 replacement :表示跳转后的内容。 flag :表示 rewrite 支持的 flag 标记。

 

 

flag标记说明

last :本条规则匹配完成后,不终止重写后的url匹配,一般用在 server 和 if 中。 break :本条规则匹配完成即终止,终止重写后的url匹配,一般使用在 location 中。 redirect :返回302临时重定向,浏览器地址会显示跳转后的URL地址。 permanent :返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。

 

rewrite 先对用户的URL访问路径或者域名进行重写,在重定向强求

rewrite 默认情况支队从域名后面的根路径开始到传递参数的?号前面的路径进行重写 http://域名/旧URL ----> http://域名/新URL

rewrite 正则表达式 /新URL; rewrite ^/ /新url

如果需要全域名路径重写要加上协议和域名 http://旧域名/URL ----> http://新域名/URL rewrite ^/(.*)$ http://新域名/$1;

如果使用标记位permanent 或redirect,http://旧域名/url ---> rewrite---> http://新域名/url --> 通过浏览器地址栏会改为http://新域名/url 再进行访问 -->location匹配跳转页面

 

(1)将请求http://bbs.kgc.com/abc/index.php的访问跳转到http://www.kgc.com/bbs/abc/index.php,保证原域名后面的uri路径不变

 

 

#添加域名重定向
 if ($host = 'www.kgc.com'){                        #$host为rewrite全局变量,代表请求主机头字段或主机名
            rewrite ^/(.*)$ http://www.benet.com/$1 permanent;    #$1为正则匹配的内容,即“域名/”之后的字符串

 

 #重启nginx

 

要求所有 IP 访问任何内容都显示一个固定维护页面,只有公司 IP :192.168.19.27访问正常

 

 #修改nginx配置文件

 

 #别的主机访问显示维护界面

#指定的服务器可以访问
 

现在访问的是 http://bbs.kgc.com/post/,现在需要将这个域名下面的访问都跳转到http://www.kgc.com/bbs/post/

 

 

 

 

 #重启nginx

 #地址跳转成功

 
 
 

 基于参数匹配的跳转

 

$request_uri:包含请求参数的原始URI,不包含主机名,如:http://www.kgc.com/abc/bbs/index.html?a=1&b=2 中的 /abc/bbs/index.php?a=1&b=2
$uri:这个变量指当前的请求URI,不包括任何参数,如:/abc/bbs/index.html
$document_uri:与$uri相同,这个变量指当前的请求URI,不包括任何传递参数,如:/abc/bbs/index.html

 

 

 #重启

 #使用浏览器访问 http://www.kgc.com/100-200-100.html 或 http://www.kgc.com/100-100-100.html 跳转到http://www.kgc.com页面。

 

基于目录下所有 php 结尾的文件跳转要求访问 http://www.kgc.com/upload/123.php 跳转到首页。

 

 

 

 

 

 

基于最普通一条 url 请求的跳转要求访问一个具体的页面如 http://www.kgc.com/abc/123.html 跳转到首页