焦点

nginx rewrite url重写

时间:2010-12-5 17:23:32  作者:百科   来源:知识  查看:  评论:0
内容摘要:nginx的rewrite指令,说白了就是帮你在URL到达后端之前,把它改头换面。这功能我天天用,但每次看到新手在配置里写一堆正则然后抓狂,都觉得挺有意思——他们总以为rewrite是万能的,其实它更

nginx的rewrite指令,说白了就是帮你在URL到达后端之前,把它改头换面。这功能我天天用,但每次看到新手在配置里写一堆正则然后抓狂,都觉得挺有意思——他们总以为rewrite是万能的,其实它更像一把手术刀,用对了能救命,用错了能放血。

先看个最常见的场景。你有个老站点,产品页URL长这样:/product.php?id=123。现在想改成伪静态的/product/123.html,为了SEO也好,为了好看也罢。这时候rewrite就上场了:

location / {  rewrite ^/product/(\d+)\.html$ /product.php?id=$1 last; } 

正则匹配路径,把数字抓出来,拼到真实的PHP地址后面。last表示重写后重新匹配location,break则直接发起内部请求。这两者的区别,当年我踩坑踩了整整一个下午——用错了,配了fastcgi_pass的location会二次匹配,结果请求跑到别的处理块里,返回404。你说冤不冤。

但rewrite能干的事远不止美化URL。举个例子,防图片盗链。别人网站直接引用你的图片,消耗你带宽,你可以在server块里加个判断:

if ($http_referer !~ "^$|http://yourdomain\.com") {  rewrite ^/images/(.*)$ /images/hotlink.jpg last; } 

不是你的referer,一律替换成一张警告图。简单粗暴,但有效。不过这里有个坑——if里用rewrite,很多人说if是邪恶的,其实nginx的if在location里确实有很多诡异行为,但在server块里做referer判断倒还算安全。我见过有人把if写进location里做rewrite,结果变量解析顺序出问题,直接白屏,排查半天。

还有个场景特别容易被忽视:HTTP跳HTTPS。很多人写:

if ($scheme = http) {  return 301 https://$host$request_uri; } 

这其实不是rewrite,是return。但很多人混着用。区别在哪?rewrite会继续处理后续规则,return直接终止。论性能,return远胜rewrite——它不涉及正则匹配,直接响应。所以能用return的地方,别纠结rewrite。

rewrite的flag也值得好好琢磨。last和break的区别我前面提了,redirect和permanent则是返回302和301给客户端——这用于URL迁移。比如你改版了,把/old/page.html永久迁移到/new/page:

rewrite ^/old/(.*)$ /new/$1 permanent; 

搜索引擎会更新索引,老链接不失效。但注意,permanent是301,浏览器会缓存,如果你之后想改回来,用户那边可能还停留在旧地址——这坑我踩过,改配置容易,清用户缓存难。

最后说点个人观察。很多人把rewrite当成URL处理的全能工具,其实它只适合简单改写。复杂的路由分发、基于cookie或header的跳转,你应该用if+return,或者干脆在应用层处理——nginx做它擅长的事,把请求转给正确的位置。我曾经接手过一个项目,配置里堆了三十多条rewrite规则,各种正则嵌套,性能差不说,出问题都没法调试。后来砍掉一半,把逻辑挪到PHP里,清爽多了。

rewrite的正则用的是PCRE,支持捕获组和反向引用。但别写太复杂的表达式——nginx每请求都要编译正则,虽然现在有缓存,但复杂正则的匹配开销依然不小。能用字符串精确匹配的,就别上正则。比如rewrite ^/about$ /about.html last;这种,直接写死路径,比^/a(bout)?$这种聪明写法快得多,也更容易让人看懂。

配置rewrite时,测试永远是第一位的。找个不用的域名或者加个测试server块,用curl打几个请求看结果。别直接上生产——我就见过有人把last写成break,导致整个站的静态资源全部404,大半夜被叫起来回滚。你写rewrite的时候,心里要清楚它只是URL改写,不是业务逻辑,不是安全策略,更不是万能药。搞清楚了边界,它就是你手里最顺手的工具之一。

最近更新
热门排行
copyright © 2026 powered by 力不从心网   sitemap