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

[经验分享] Nginx的location匹配规则

[复制链接]

尚未签到

发表于 2016-12-24 10:44:40 | 显示全部楼层 |阅读模式
  


Nginx的重定向用到了Nginx的HttpRewriteModule,下面简单解释以下如何使用的方法:

rewrite命令

nginx的rewrite相当于apache的rewriterule(大多数情况下可以把原有apache的rewrite规则加上引号就可以直接使用),它可以用在server,location 和IF条件判断块中,命令格式如下:
rewrite 正则表达式 替换目标 flag标记
flag标记可以用以下几种格式:
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301
例如下面这段设定nginx将某个目录下面的文件重定向到另一个目录,$2对应第二个括号(.*)中对应的字符串:
location /download/ {
rewrite ^(/download/.*)/m/(.*)\..*$ $1/nginx-rewrite/$2.gz break;
}


nginx重定向的IF条件判断


在server和location两种情况下可以使用nginx的IF条件判断,条件可以为以下几种:
正则表达式
如:
匹配判断

~  为区分大小写匹配; !~为区分大小写不匹配
 ~* 为不区分大小写匹配;!~为不区分大小写不匹配
例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1 break;
}
文件和目录判断
  -f和!-f判断是否存在文件
 -d和!-d判断是否存在目录
 -e和!-e判断是否存在文件或目录
 -x和!-x判断文件是否可执行
例如下面设定nginx在文件和目录不存在的时候重定向:
if (!-e $request_filename) {
proxy_pass http://127.0.0.1;
}

return

返回http代码,例如设置nginx防盗链:
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;
if ($invalid_referer) {
return 404;
}
}











nginx内使用正则表达式(花括号)需要注意的问题

2010年05月24日 星期一 13:42

朋友为对付一些乱七八糟网站的盗链,于是就在nginx配置文件内写了一个正则来禁止那些域名,他写的是这个样子:

if ($http_referer ~* .*([0-9]{2,3}[a-z]{3}\.com|ffkkk\.net|444nnn\.net)) {
return   403;
}

但是用nginx -t来测试nginx配置文件语法的时候报错,提示在[0-9]这里有错。我看了看,正则写的没有问题呀,怀疑是[]的问题,我自己以前没有在ngnix内用过[],就简化了下:

if ($http_referer ~* .*[0-9]\.com) {
return   403;
}

用上面这个配置语法测试通过了。说明[]是可以直接用的,这样试过之后我恍然大悟,确定是{}的问题,因为nginx内{}是用来表示配置段的,直接用肯定有问题。但是在nginx的配置文件内,难道正则就不能用{}了吗?

肯定是可以的,要不然也太弱智了,经过google,终于找到答案:原来如果正则内有用{}的话,只要在正则的两边加上单引号或双引号就行了。

所以写成这样子就通过了:

if ($http_referer ~* "^.*[0-9]{2,3}[a-z]{3}\.com") {
return   403;
}


参考:http://www.nginxcn.com/doc/standard/httprewrite.html
注: 对花括号( { 和 } )来说, 他们既能用在重定向的正则表达式里,也是用在配置文件里分割代码块, 为了避免冲突, 正则表达式里带花括号的话,应该用双引号(或者单引号)包围。比如,要将类似以下的url



/photos/123456
重定向到:


/path/to/photos/12/1234/123456.png
可以用以下方法 (注意双引号):

rewrite  "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;











nginx 正则

November 12th, 2010 by admin Leave a reply »
location
syntax: location [=|~|~*|^~] /uri/ { … }
语法:location [=|~|~*|^~] /uri/ { … }
default: no
默认:否
 
context: server
上下文:server
This directive allows different configurations depending on the URI. It can be configured using both conventional strings and regular expressions. To use regular expressions, you must use the prefix ~* for case insensitive match and ~ for case sensitive match.
这个指令随URL不同而接受不同的结构。你可以配置使用常规字符串和正则表达式。如果使用正则表达式,你必须使用 ~* 前缀选择不区分大小写的匹配或者 ~ 选择区分大小写的匹配。
To determine which location directive matches a particular query, the conventional strings are checked first. Conventional strings match the beginning portion of the query and are case-sensitive – the most specific match will be used (see below on how nginx determines this). Afterwards, regular expressions are checked in the order defined in the configuration file. The first regular expression to match the query will stop the search. If no regular expression matches are found, the result from the convention string search is used.
确定 哪个location 指令匹配一个特定指令,常规字符串第一个测试。常规字符串匹配请求的开始部分并且区分大小写,最明确的匹配将会被使用(查看下文明白 nginx 怎么确定它)。然后正则表达式按照配置文件里的顺序测试。找到第一个比配的正则表达式将停止搜索。如果没有找到匹配的正则表达式,使用常规字符串的结果。
There are two ways to modify this behavior. The first is to use the prefix “=”, which matches an exact query only. If the query matches, then searching stops and the request is handled immediately. For example, if the request “/” occurs frequently, then using “location = /” will expedite the processing of this request.
有两个方法修改这个行为。第一个方法是使用 “=”前缀,将只执行严格匹配。如果这个查询匹配,那么将停止搜索并立即处理这个请求。例子:如果经常发生”/”请求,那么使用 “location = /” 将加速处理这个请求。
The second is to use the prefix ^~. This prefix is used with a conventional string and tells nginx to not check regular expressions if the path provided is a match. For instance, “location ^~ /images/” would halt searching if the query begins with /images/ – all regular expression directives would not be checked.
第二个是使用 ^~ 前缀。如果把这个前缀用于一个常规字符串那么告诉nginx 如果路径匹配那么不测试正则表达式。
Furthermore it is important to know that NGINX does the comparison not URL encoded, so if you have a URL like “/images/%20/test” then use “/images/ /test” to determine the location.
而且它重要在于 NGINX 做比较没有 URL 编码,所以如果你有一个 URL 链接’/images/%20/test’ , 那么使用 “images/ /test” 限定location。
To summarize, the order in which directives are checked is as follows:
总结,指令按下列顺序被接受:
1. Directives with the = prefix that match the query exactly. If found, searching stops.
1. = 前缀的指令严格匹配这个查询。如果找到,停止搜索。
2. All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops.
2. 剩下的常规字符串,长的在前。如果这个匹配使用 ^~ 前缀,搜索停止。
3. Regular expressions, in order of definition in the configuration file.
3. 正则表达式,按配置文件里的顺序。
4. If #3 yielded a match, that result is used. Else the match from #2 is used.
4. 如果第三步产生匹配,则使用这个结果。否则使用第二步的匹配结果。
Example:
例子:
location = / {
# matches the query / only.
# 只匹配 / 查询。
[ configuration A ]
}
location / {
# matches any query, since all queries begin with /, but regular
# expressions and any longer conventional blocks will be
# matched first.
# 匹配任何查询,因为所有请求都已 / 开头。但是正则表达式规则和长的块规则将被优先和查询匹配。
[ configuration B ]
}
location ^~ /images/ {
# matches any query beginning with /images/ and halts searching,
# so regular expressions will not be checked.
# 匹配任何已 /images/ 开头的任何查询并且停止搜索。任何正则表达式将不会被测试。
[ configuration C ]
}
location ~* “.(gif|jpg|jpeg)$ {
# matches any request ending in gif, jpg, or jpeg. However, all
# requests to the /images/ directory will be handled by
# Configuration C.
# 匹配任何已 gif、jpg 或 jpeg 结尾的请求。然而所有 /images/ 目录的请求将使用 Configuration C。
[ configuration D ]
}
Example requests:
例子请求:
*
/ -> configuration A
*
/documents/document.html -> configuration B
*
/images/1.gif -> configuration C
*
/documents/1.jpg -> configuration D
Note that you could define these 4 configurations in any order and the results would remain the same.
注意:按任意顺序定义这4个配置结果将仍然一样。

Nginx Location 语法,与简单配置

一、介绍Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器.
二、Location语法语法:location [=|~|~*|^~] /uri/ { … }
注:
1、~   为区分大小写匹配
2、~* 为不区分大小写匹配
3、!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
示例一:
location  / { }
匹配任何查询,因为所有请求都以 / 开头。但是正则表达式规则将被优先和查询匹配。
示例二:
location =/ {}
仅仅匹配/
示例三:
location ~* \.(gif|jpg|jpeg)$ {
rewrite \.(gif|jpg)$ /logo.png;

注:不区分大小写匹配任何以gif,jpg,jpeg结尾的文件
三、ReWrite语法
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301
1、下面是可以用来判断的表达式:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
2、下面是可以用作判断的全局变量
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php
四、Redirect语法
server {
listen 80;
server_name start.igrow.cn;
index index.html index.php;
root html;
if ($http_host !~ “^star\.igrow\.cn
正则表达式匹配,其中:


  • * ~ 为区分大小写匹配
  • * ~* 为不区分大小写匹配
  • * !~和!~*分别为区分大小写不匹配及不区分大小写不匹配


文件及目录匹配,其中:


  • * -f和!-f用来判断是否存在文件
  • * -d和!-d用来判断是否存在目录
  • * -e和!-e用来判断是否存在文件或目录
  • * -x和!-x用来判断文件是否可执行


flag标记有:


  • * last 相当于Apache里的[L]标记,表示完成rewrite
  • * break 终止匹配, 不再匹配后面的规则
  • * redirect 返回302临时重定向 地址栏会显示跳转后的地址
  • * permanent 返回301永久重定向 地址栏会显示跳转后的地址


一些可用的全局变量有,可以用做条件判断(待补全)


  • $args
  • $content_length
  • $content_type
  • $document_root
  • $document_uri
  • $host
  • $http_user_agent
  • $http_cookie
  • $limit_rate
  • $request_body_file
  • $request_method
  • $remote_addr
  • $remote_port
  • $remote_user
  • $request_filename
  • $request_uri
  • $query_string
  • $scheme
  • $server_protocol
  • $server_addr
  • $server_name
  • $server_port
  • $uri


结合QeePHP的例子


  • if (!-d $request_filename) {
  • rewrite ^/([a-z-A-Z]+)/([a-z-A-Z]+)/?(.*)$ /index.php?namespace=user&controller=$1&action=$2&$3 last;
  • rewrite ^/([a-z-A-Z]+)/?$ /index.php?namespace=user&controller=$1 last;
  • break;


多目录转成参数
abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2


  • if ($host ~* (.*)\.domain\.com) {
  • set $sub_name $1;
  • rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last;
  • }


目录对换
/123456/xxxx -> /xxxx?id=123456


  • rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;


例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:


  • if ($http_user_agent ~ MSIE) {
  • rewrite ^(.*)$ /nginx-ie/$1 break;
  • }


目录自动加“/”


  • if (-d $request_filename){
  • rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
  • }


禁止htaccess


  • location ~/\.ht {
  • deny all;
  • }


禁止多个目录


  • location ~ ^/(cron|templates)/ {
  • deny all;
  • break;
  • }


禁止以/data开头的文件
可以禁止/data/下多级目录下.log.txt等请求;


  • location ~ ^/data {
  • deny all;
  • }


禁止单个目录
不能禁止.log.txt能请求


  • location /searchword/cron/ {
  • deny all;
  • }


禁止单个文件


  • location ~ /data/sql/data.sql {
  • deny all;
  • }


给favicon.ico和robots.txt设置过期时间;
这里为favicon.ico为99天,robots.txt为7天并不记录404错误日志


  • location ~(favicon.ico) {
  • log_not_found off;
  • expires 99d;
  • break;
  • }

  • location ~(robots.txt) {
  • log_not_found off;
  • expires 7d;
  • break;
  • }


设定某个文件的过期时间;这里为600秒,并不记录访问日志


  • location ^~ /html/scripts/loadhead_1.js {
  • access_log off;
  • root /opt/lampp/htdocs/web;
  • expires 600;
  • break;
  • }


文件反盗链并设置过期时间
这里的return 412 为自定义的http状态码,默认为403,方便找出正确的盗链的请求
“rewrite ^/ http://leech.c1gstudio.com/leech.gif;”显示一张防盗链图片
“access_log off;”不记录访问日志,减轻压力
“expires 3d”所有文件3天的浏览器缓存


  • location ~* ^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {
  • valid_referers none blocked *.c1gstudio.com *.c1gstudio.net localhost 208.97.167.194;
  • if ($invalid_referer) {
  • rewrite ^/ http://leech.c1gstudio.com/leech.gif;
  • return 412;
  • break;
  • }
  • access_log off;
  • root /opt/lampp/htdocs/web;
  • expires 3d;
  • break;
  • }


只充许固定ip访问网站,并加上密码


  • root /opt/htdocs/www;
  • allow 208.97.167.194;
  • allow 222.33.1.2;
  • allow 231.152.49.4;
  • deny all;
  • auth_basic “C1G_ADMIN”;
  • auth_basic_user_file htpasswd;


将多级目录下的文件转成一个文件,增强seo效果
/job-123-456-789.html 指向/job/123/456/789.html


  • rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;


将根目录下某个文件夹指向2级目录
如/shanghaijob/ 指向 /area/shanghai/
如果你将last改成permanent,那么浏览器地址栏显是/location/shanghai/


  • rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;


上面例子有个问题是访问/shanghai 时将不会匹配


  • rewrite ^/([0-9a-z]+)job$ /area/$1/ last;
  • rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;


这样/shanghai 也可以访问了,但页面中的相对链接无法使用,
如./list_1.html真实地址是/area/shanghia/list_1.html会变成/list_1.html,导至无法访问。
那我加上自动跳转也是不行咯
(-d $request_filename)它有个条件是必需为真实目录,而我的rewrite不是的,所以没有效果


  • if (-d $request_filename){
  • rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
  • }


知道原因后就好办了,让我手动跳转吧


  • rewrite ^/([0-9a-z]+)job$ /$1job/ permanent;
  • rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;


文件和目录不存在的时候重定向:


  • if (!-e $request_filename) {
  • proxy_pass http://127.0.0.1;
  • }


域名跳转


  • server
  • {
  • listen 80;
  • server_name jump.c1gstudio.com;
  • index index.html index.htm index.php;
  • root /opt/lampp/htdocs/www;
  • rewrite ^/ http://www.c1gstudio.com/;
  • access_log off;
  • }


多域名转向


  • server_name www.c1gstudio.com www.c1gstudio.net;
  • index index.html index.htm index.php;
  • root /opt/lampp/htdocs;
  • if ($host ~ “c1gstudio\.net”) {
  • rewrite ^(.*) http://www.c1gstudio.com$1 permanent;
  • }


三级域名跳转


  • if ($http_host ~* “^(.*)\.i\.c1gstudio\.com$”) {
  • rewrite ^(.*) http://top.yingjiesheng.com$1;
  • break;
  • }


域名镜向


  • server
  • {
  • listen 80;
  • server_name mirror.c1gstudio.com;
  • index index.html index.htm index.php;
  • root /opt/lampp/htdocs/www;
  • rewrite ^/(.*) http://www.c1gstudio.com/$1 last;
  • access_log off;
  • }


某个子目录作镜向


  • location ^~ /zhaopinhui {
  • rewrite ^.+ http://zph.c1gstudio.com/ last;
  • break;
  • }


discuz ucenter home (uchome) rewrite


  • rewrite ^/(space|network)-(.+)\.html$ /$1.php?rewrite=$2 last;
  • rewrite ^/(space|network)\.html$ /$1.php last;
  • rewrite ^/([0-9]+)$ /space.php?uid=$1 last;


discuz 7 rewrite


  • rewrite ^(.*)/archiver/((fid|tid)-[\w\-]+\.html)$ $1/archiver/index.php?$2 last;
  • rewrite ^(.*)/forum-([0-9]+)-([0-9]+)\.html$ $1/forumdisplay.php?fid=$2&page=$3 last;
  • rewrite ^(.*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/viewthread.php?tid=$2&extra=page\%3D$4&page=$3 last;
  • rewrite ^(.*)/profile-(username|uid)-(.+)\.html$ $1/viewpro.php?$2=$3 last;
  • rewrite ^(.*)/space-(username|uid)-(.+)\.html$ $1/space.php?$2=$3 last;
  • rewrite ^(.*)/tag-(.+)\.html$ $1/tag.php?name=$2 last;


给discuz某版块单独配置域名


  • server_name bbs.c1gstudio.com news.c1gstudio.com;

  • location = / {
  • if ($http_host ~ news\.c1gstudio.com$) {
  • rewrite ^.+ http://news.c1gstudio.com/forum-831-1.html last;
  • break;
  • }
  • }


discuz ucenter 头像 rewrite 优化


  • location ^~ /ucenter {
  • location ~ .*\.php?$
  • {
  • #fastcgi_pass unix:/tmp/php-cgi.sock;
  • fastcgi_pass 127.0.0.1:9000;
  • fastcgi_index index.php;
  • include fcgi.conf;
  • }

  • location /ucenter/data/avatar {
  • log_not_found off;
  • access_log off;
  • location ~ /(.*)_big\.jpg$ {
  • error_page 404 /ucenter/images/noavatar_big.gif;
  • }
  • location ~ /(.*)_middle\.jpg$ {
  • error_page 404 /ucenter/images/noavatar_middle.gif;
  • }
  • location ~ /(.*)_small\.jpg$ {
  • error_page 404 /ucenter/images/noavatar_small.gif;
  • }
  • expires 300;
  • break;
  • }
  • }


jspace rewrite


  • location ~ .*\.php?$
  • {
  • #fastcgi_pass unix:/tmp/php-cgi.sock;
  • fastcgi_pass 127.0.0.1:9000;
  • fastcgi_index index.php;
  • include fcgi.conf;
  • }

  • location ~* ^/index.php/
  • {
  • rewrite ^/index.php/(.*) /index.php?$1 break;
  • fastcgi_pass 127.0.0.1:9000;
  • fastcgi_index index.php;
  • include fcgi.conf;
  • }


amp;quot http://extra-001.yo2cdn.com/wp-includes/images/smilies/icon_wink.gif {
rewrite ^(.*) http://star.igrow.cn$1 redirect;
}
}
五、防盗链location ~* \.(gif|jpg|swf)$ {
valid_referers none blocked start.igrow.cn sta.igrow.cn;
if ($invalid_referer) {
rewrite ^/ http://$host/logo.png;
}
}
六、根据文件类型设置过期时间
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
expires    1h;
break;
}
}
七、禁止访问某个目录
location ~* \.(txt|doc)${
root /data/www/wwwroot/linuxtone/test;
deny all;
}

XX


运维网声明 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.iyunv.com/thread-318761-1-1.html 上篇帖子: nginx启动报错nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 下篇帖子: Nginx 源码编译参数详细列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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