nginx rewrite基本用法
rewrite支持使用 if,set,正则,文件和目录判断
正则表达式匹配:
符号 说明
= 等值的比较
~ 与指定正则表达式模式匹配,区分字符大小写
~* 与指定正则表达式模式匹配,不区分字符大小写
!~ 与指定正则表达式模式不匹配,区分字符大小写
!~* 与指定正则表达式模式不匹配,不区分字符大小写
文件及目录匹配:
符号 说明
-f ,!-f 判断指定路径的文件是否存在
-d, !-d 判断指定路径的目录是否存在
-e, !-e 判断指定路径的文件或目录是否存在
-x, !-x 判断指定路径的文件是否存在且可执行
-r,!-r 判断指定路径的文件是否存在且可读
-w,!-w 判断指定路径的文件是否存在且可写
例子:
1. 判断一个url请求中是否含有敏感字符,包含敏感字符则拒绝请求
location /{ #获取url完整请求 set $URL $scheme://$http_host$request_uri; #根据获取的URL匹配一些限制字符,满足条件拒绝访 #这里以www字符为例,可自行修改 if ($URL ~ "fuck"){ echo "请求带有敏感字符'fuck',拒绝访问!"; #重定向到首页 #rewrite ^/(.*) http://www.home.com/ permanent; } echo "正常访问,url=" $URL; }
2. 去除 /apis 路径
将 /apis/user/1 重写为 /user/1
location /apis { proxy_pass http://127.0.0.1:8000/; proxy_pass_request_headers on; # 重写URL 去除apis rewrite "^/apis/(.*)$" /$1 break; }
3. 修改url路径,保持用户习惯
将imgs重写到images
location /imgs { rewrite ^/imgs/(.*\.jpg)$ /images/$1 break; }
4. 浏览器分离
// IE和chrome分别访问不同的url
if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } if ($http_user_agent ~ Chrome) { rewrite ^(.*)$ /chrome/$1 break; }
5. 常见各种路径跳转
server { # 访问 /last.html 的时候,页面内容重写到 /index.html 中,并继续后面的匹配,浏览器地址栏URL地址不变 rewrite /last.html /index.html last; # 访问 /break.html 的时候,页面内容重写到 /index.html 中,并停止后续的匹配,浏览器地址栏URL地址不变; rewrite /break.html /index.html break; # 访问 /redirect.html 的时候,页面直接302定向到 /index.html中,浏览器地址URL跳为index.html rewrite /redirect.html /index.html redirect; # 访问 /permanent.html 的时候,页面直接301定向到 /index.html中,浏览器地址URL跳为index.html rewrite /permanent.html /index.html permanent; # 把 /html/*.html => /post/*.html ,301定向 rewrite ^/html/(.+?).html$ /post/$1.html permanent; # 把当前域名的请求,跳转到新域名上,域名变化但路径不变 rewrite ^/(.*) http://www.jd.com/$1 permanent; }
6. 常见path参数转query_string
server { # 把 /search/key => /search.html?keyword=key rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent; # 对/images/bla_500x400.jpg文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。 rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last; }
7. 禁止访问
# 禁止指定IP访问 location / { if ($remote_addr = 192.168.1.253) { return 403; } } # 禁止多个目录 location ~ ^/(cron|templates)/ { deny all; break; }
8. 隐藏真实目录
server { root /var/www/html; # 用 /html_test 来掩饰 html location / { # 使用break拿一旦匹配成功则忽略后续location rewrite /html_test /html break; } # 访问真实地址直接报没权限 location /html { return 403; } }
9. 文件名和参数重写
location = /index.html { # 修改默认值为 set $name test; # 如果参数中有 name=xx 则使用该值 if ($args ~* name=(\w+?)(&|$)) { set $name $1; } # permanent 301重定向 rewrite ^ /$name.html permanent; }
10 域名拦截
# 拦截百度 if ($http_referer ~ 'baidu.com') { # return 404; return 200 "<html><script>window.location.href='//$host$request_uri';</script></html>"; } # 如果host是www.360buy.com,即非jd.com,则301到www.jd.com中 if ( $host != "www.jd.com" ){ rewrite ^/(.*)$ https://www.jd.com/$1 permanent; }
11. 方法,文件,cookie,速率等拦截
# 如果文件不存在则返回400 if (!-f $request_filename) { return 400; } # 如果请求类型是POST则返回405,return不能返回301,302 if ($request_method = POST) { return 405; } # 如果参数中有 a=1 则301到指定域名 if ($args ~ a=1) { rewrite ^ http://example.com/ permanent; } # 如果请求的文件不存在,则反向代理到localhost 。这里的break也是停止继续rewrite if (!-f $request_filename){ break; proxy_pass http://127.0.0.1; } if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set $id $1; } if ($request_method = POST) { return 405; } if ($slow) { limit_rate 10k; } if ($invalid_referer) { return 403; }
参考:https://www.jianshu.com/p/10ecc107b5ee
https://blog.csdn.net/qq_36532540/article/details/103490016