嘿,伙计们!今天咱们不聊Nginx怎么装、怎么配反向代理那些“基本功”。那些都太“小儿科”了,是时候玩点高级的了!你有没有遇到过这些让人抓狂的场景:
“那个该死的爬虫,天天来扫我的后台登录页面,日志都爆了!”“我的网站换了新版,旧URL一大堆,怎么让用户无感跳转到新地址?”“我想只允许某个特定目录下的图片被外部引用,其他的统统拦截!”当你挠着头,在网上搜索解决方案时,十个答案里有八个会甩给你一行像天书一样的代码,里面充满了各种奇奇怪怪的符号,比如
location ~* .(php|asp)$ 或者
rewrite ^/old/(.*)$ /new/$1 permanent;。
这时候你是什么感觉?是不是觉得:“我只是想解决个小问题,怎么还得先学一门外星语?”
别怕!今天,我就要为你揭开这层神秘的面纱。这套“外星语”的真身,就是——正则表达式。它不是什么洪水猛兽,而是你手中一把锋利无比的“瑞士军刀”。一旦掌握,你就能从被Nginx配置“牵着鼻子走”的菜鸟,进化成随心所欲制定规则的“服务器巫师”!
咱们打个比方。你用Word或者记事本的时候,用过“查找”功能吧?输入“hello”,它就能帮你找到所有“hello”。
正则表达式,就是一种超级加强版的“查找”工具。它不仅能找“hello”,还能找:
“以h开头,以o结尾的任意单词”“所有看起来像邮箱地址的字符串”“所有手机号码”“出现在一行开头的特定词语”在Nginx里,我们就是利用这种“超级查找”能力,来匹配浏览器发来的请求URL、请求头等等,然后针对匹配到的请求,执行我们想要的特殊操作(比如重写、转发、禁止访问)。
好了,理论课结束,实战开始!下面这些就是你必须掌握的“基础魔咒”。别死记硬背,边看边在脑子里想象它匹配的场景。
^ - 字符串的“起跑线”
咒语含义:匹配字符串的开始位置。示例:
^/admin 只会匹配以
/admin 开头的URL,比如
/admin/login,但不会匹配
/user/admin。
$ - 字符串的“终点线”
咒语含义:匹配字符串的结束位置。示例:
.html$ 只会匹配以
.html 结尾的URL,比如
index.html,但不会匹配
index.html?param=1(因为后面还有东西)。
. - 传说中的“万能牌”
咒语含义:匹配任意一个单个字符(除了换行符)。示例:
/u.er 可以匹配
/user、
/u@er、
/u-er 等等。
* - “从零到无穷”的重复使者
咒语含义:匹配前面的字符零次或多次。示例:
/ab*c 可以匹配
/ac(b出现0次)、
/abc(b出现1次)、
/abbbbc(b出现N次)。是不是很贪心?
+ - “至少一次”的执着狂
咒语含义:匹配前面的字符一次或多次。示例:
/ab+c 可以匹配
/abc、
/abbbbc,但不能匹配
/ac。它要求b至少得出场一回。
? - “可有可无”的随和派
咒语含义:匹配前面的字符零次或一次。示例:
/https? 可以匹配
http(s出现0次)和
https(s出现1次)。用来匹配两种协议,非常方便。
- “解除魔法”的转义符
咒语含义:当一个字符有特殊含义时(比如
. 是万能牌),你想让它变回普通的“点”,就需要用
来转义它。示例:我们要匹配真正的文件名后缀
.php,这里的
. 就不是“任意字符”了,而是一个实实在在的英文句点。
( ) - “抓取小队”的括号
咒语含义:定义一个子表达式,更重要的是,它能把匹配到的内容临时保存起来,供后面使用。示例:
^/user/(d+) 可以匹配
/user/123,并且把
123 这个数字抓取出来,后面可以用
$1 来引用它。如果有第二组
( ),就是
$2,以此类推。
| - “二选一”的选择器
咒语含义:相当于逻辑上的“或”。示例:
(jpg|png|gif) 可以匹配
jpg、
png 或
gif。常用于匹配多种文件类型。
光说不练假把式。现在,让我们把这些“魔咒”注入到Nginx的配置文件中,看看能产生怎样神奇的化学反应!
Nginx里最常用到正则的两个地方是
location 块 和
rewrite 指令。
location 精准定位,当好“流量交警”
location 的作用是根据请求的URI,将流量引导到不同的处理逻辑。
location = /path:精确匹配。只匹配完全一样的URI,优先级最高。
location ^~ /path:前缀匹配。匹配以指定路径开头的URI,优先级仅次于精确匹配,且一旦匹配不再检查正则。
location ~ pattern:区分大小写的正则匹配。
location ~* pattern:不区分大小写的正则匹配(更常用)。
location /path:普通前缀匹配。优先级最低。
完整示例1:保卫我们的后台,拦截恶意扫描!
假设我们的后台地址是
/admin,总有些坏蛋用工具扫描
/admin.php,
/admin/,
/admin/login.php 等。
server {
listen 80;
server_name yoursite.com;
# 场景1.1:精准屏蔽 admin.php 的直接访问
location = /admin.php {
deny all; # 直接拒绝访问
return 404; # 并且返回404,让它以为页面不存在
}
# 场景1.2:屏蔽所有以 /admin 开头的请求(根据实际情况调整)
# 如果你根本没有后台,或者后台在其他路径,可以这样一刀切
location ^~ /admin {
deny all;
return 404;
}
# 场景1.3:更智能的屏蔽,只允许你自己的IP访问真实后台
location ~* ^/admin(/.*)?$ {
allow 192.168.1.100; # 替换成你的公网IP
deny all;
# 这里可以继续代理到你的后端应用,比如:
# proxy_pass http://backend_server;
}
# 你网站的其他正常配置...
location / {
try_files $uri $uri/ /index.html;
}
}
完整示例2:动静分离,用正则给静态资源开“绿色通道”
图片、CSS、JS这些静态文件,应该被高效地处理。
server {
listen 80;
server_name yoursite.com;
# 静态资源:用正则匹配常见后缀,并设置浏览器缓存
location ~* .(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {
# 静态资源通常放在某个特定目录下,比如 /static/ 或 /assets/
root /path/to/your/static/files;
# 设置缓存时间,减轻服务器压力
expires 30d;
# 尝试直接访问文件,没有就404
try_files $uri =404;
}
# 动态请求:交给后端应用服务器处理(比如PHP,Python)
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
# ... 其他fastcgi参数
}
# 根路径和其他路由交给前端路由处理(适用于Vue/React等SPA应用)
location / {
root /path/to/your/webroot;
try_files $uri $uri/ /index.html;
}
}
rewrite 玩转URL“变装秀”
rewrite 是URL重写神器,常用于旧链接跳转、美化URL等。
rewrite regex replacement [flag];
regex:匹配URI的正则模式。
replacement:替换后的字符串,可以用
$1,
$2 引用前面
( ) 抓取的内容。
flag:
last:用新的URI重新发起一轮location匹配。
break:终止当前脚本的后续rewrite指令,在当前location继续处理。
redirect:返回302临时重定向。
permanent:返回301永久重定向(SEO友好)。
完整示例3:网站改版,旧文章链接批量跳转
旧版文章URL是
/article-123.html,新版是
/posts/123。
server {
listen 80;
server_name yoursite.com;
# 重写规则:将 /article-数字.html 永久重定向到 /posts/数字
rewrite ^/article-(d+).html$ /posts/$1 permanent;
# 新版本的路由处理
location /posts/ {
# 这里可能是你的新版本应用逻辑
# 例如,代理到某个应用
proxy_pass http://your_app_server;
}
}
当用户访问
yoursite.com/article-55.html 时,Nginx会立刻返回一个301跳转,指引浏览器去访问
yoursite.com/posts/55。
完整示例4:强制HTTPS和统一域名,打造专业形象
server {
listen 80;
server_name www.yoursite.com yoursite.com; # 同时监听带www和不带www
# 场景4.1:强制将所有HTTP流量跳转到HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name yoursite.com; # 这里只监听不带www的域名
# SSL证书配置...
# 场景4.2:强制将带www的HTTPS域名,统一到不带www的域名(SEO最佳实践)
if ($host = 'www.yoursite.com') {
return 301 https://yoursite.com$request_uri;
}
# 你的主网站配置...
}
location 的优先级顺序:
= >
^~ >
~/
~* >
普通前缀。配置时脑子要清晰,别让规则之间“打架”。性能!性能!性能!:正则虽然强大,但比前缀匹配消耗更多CPU。尽量避免过于复杂和低效的正则,尤其在高并发环境下。把最常访问的、精确的匹配放在前面。多用
^~ 避免不必要的正则检查:如果你确定某个路径不需要正则,就用
^~,Nginx匹配到它后就会停止搜索正则,提升效率。善用
$1, $2:
rewrite 的灵魂就在于
( ) 和
$1 的配合使用,这是实现动态重写的关键。测试!测试!再测试!:修改Nginx配置前一定要备份!用
nginx -t 测试语法是否正确。上线后密切观察日志,确认规则按预期工作。
看吧,Nginx的正则表达式并没有想象中那么可怕。它就像一套威力强大的“组合拳”,一旦你熟悉了每个招式的用法,就能在服务器的世界里“呼风唤雨”。
从今天起,你可以:
淡定地给恶意爬虫设置“路障”。优雅地完成网站URL的“新陈代谢”。高效地管理你的静态资源。打造一个更安全、更规范、更专业的网站入口。现在,打开你的Nginx配置文件,大胆地去实践、去修改、去创造吧!记住,每一个优秀的运维工程师和后端开发者,都是一位深谙此道的“规则巫师”。
祝你在Nginx的魔法世界里,玩得开心!