且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

D9-New-Nginx-Rewrite

更新时间:2022-09-24 23:21:40

D9-New-Nginx-Rewrite


首先看几个例子!

例子1

Discuz(X2.5) URL 静态化(伪静态)


  1. 页面            标记                               格式               
  2. 1 门户专题页    {name}                      topic-{name}.html 
  3. 2 门户文章页    {id}, {page}               article-{id}-{page}.html 
  4. 3 论坛主题列表页 {fid}, {page}               forum-{fid}-{page}.html 
  5. 4 论坛主题内容页 {tid}, {page}, {prevpage}   thread-{tid}-{page}-{prevpage}.html    
  6. 5 群组主题列表页 {fid}, {page}              group-{fid}-{page}.html 
  7. 6 用户个人主页    {user}, {value}            space-{user}-{value}.html 
  8. 7 用户日志内容页 {uid}, {blogid}           blog-{uid}-{blogid}.html 

Nginx Rewrite 代码


  1. rewrite ^/$ /forum.php last; 
  2. rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topicid=$2 last; 
  3. rewrite ^([^\.]*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3 last; 
  4. rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last; 
  5. rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last; 
  6. rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last; 
  7. rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last; 
  8. rewrite ^([^\.]*)/blog-([0-9]+)-([0-9]+)\.html$ $1/home.php?mod=space&uid=$2&do=blog&id=$3 last; 
  9. if (!-e $request_filename) { 
  10.     return 404; 

Nginx Rewrite 过程
论坛主题列表页    {fid}, {page}              forum-{fid}-{page}.html
browser 
http://bbs.test.com/forum-2-1.html
  |
nginx rewrite
rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last;
  |
real url
http://bbs.test.com/forum.php?mod=forumdisplay&fid=2&page=1

论坛主题内容页    {tid}, {page}, {prevpage}     thread-{tid}-{page}-{prevpage}.html
browser 
http://bbs.test.com/thread-8-1-1.html
  |
nginx rewrite
rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;
  |
real url
http://bbs.test.com/forum.php?mod=viewthread&tid=8&extra=page%3D1&page=1


例子2
Wordpress(3.4.1) 固定链接设置(伪静态)
默认                  http://blog.test.com/?p=123
月份和名称型     http://blog.test.com/index.php/2012/08/sample-post/
                                                     /index.php/%year%/%monthnum%/%postname%/

Nginx Rewrite 代码   


  1. if (-f $request_filename/index.html) 
  2. {   
  3.   rewrite (.*) $1/index.php last; 
  4. }   
  5.     
  6. if (-f $request_filename/index.php) 
  7. {   
  8.   rewrite (.*) $1/index.php last; 
  9. }   
  10.  
  11. if (!-f $request_filename) 
  12.   rewrite (.*) /index.php last; 
  13. }   

Nginx Rewrite 过程
browser 
http://blog.test.com/index.php/2012/08/vc-load/v9-1/
  |
nginx rewrite
rewrite (.*) /index.php last;
  |
real url
http://blog.test.com/?attachment_id=149


例子3


  1. rewrite ^/bus/index.php /bus/bus_city.php last; 
  2. rewrite ^/bus/$ /bus/bus_city.php last; 
  3. if ($host ~* ^bus\.domain\.com$) 
  4.   rewrite ^/$ /bus/index.php last; 
  5.  
  6. if ($var_pay_public ~ '1') 
  7.   rewrite ^(.*)$ /pay/index.php last; 
  8.  
  9. if ($host ~* ^www(.*?) ) 
  10.   rewrite  ^/xiaoqu(.*)$ /xiaoqu_2_404/; 


例子4 
http://abc.com/products.php?id=39-0-0-10
重写为
http://abc.com/products/39-0-0-10.html
Nginx Rewrite 代码


  1. rewrite ^/products/(*)\.html$ /products/products.php?id=$1 last; 



URL重写模块
1 URL重写模块
这个模块允许使用正则表达式重写URI(需PCRE库),并且可以根据相关变量重定向和选择不同的配置。
如果这个指令在server字段中指定,那么将在被请求的location确定之前执行,如果在指令执行后所选择的location中有其他的重写规则,那么它们也被执行
如果在location中执行这个指令产生了新的URI,那么location又一次确定了新的URI,这样的循环可以最多执行10次超过以后nginx将返回500错误

2 指令 
2.1 break


  1. 语法:break 
  2. 默认值:none 
  3. 使用字段:server, location, if 
  4. 完成当前设置的规则,停止执行其他的重写指令。 

示例:


  1. if ($slow) { 
  2.   limit_rate  10k; 
  3.   break; 


2.2 return


  1. 语法:return code 
  2. 默认值:none 
  3. 使用字段:server, location, if 
  4. 这个指令结束执行配置语句并为客户端返回状态代码,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416与500-504。 
  5. 此外,非标准代码444将关闭连接并且不发送任何的头部。 


2.3 set


  1. 语法:set variable value 
  2. 默认值:none 
  3. 使用字段:server, location, if 
  4. 指令设置一个变量并为其赋值,其值可以是文本,变量和它们的组合。 
  5. 你可以使用set定义一个新的变量,但是不能使用set设置$http_xxx头部变量的值 

示例:


  1. if ($request_uri ~* ".*\.(js|ico|gif|jpg|png|css)$") 
  2.   set $var_public '0'; 
  3. if ($var_public ~ '0'
  4.   rewrite ^(.*)$ /static/$1 last; 
  5. }     


2.4 if


  1. 语法:if (condition) { … }
  2. 默认值:none 
  3. 使用字段:server, location 
  4. 注意:在使用if指令之前请查看if is evil page并且尽量考虑用try_files代替。 
  5. 判断一个条件,如果条件成立,则后面的大括号内的语句将执行,相关配置从上级继承。 

可以在判断语句中指定下列值
   1 一个变量的名称;不成立的值为:空字符传”“或者一些用“0”开始的字符串。#
   2 一个使用=或者!=运算符的比较语句
   3 使用符号~*和~模式匹配的正则表达式
    ~为区分大小写的匹配。
    ~*不区分大小写的匹配(firefox匹配FireFox)。
    !~和!~*意为“不匹配的”。
   4 使用-f和!-f检查一个文件是否存在。
   5 使用-d和!-d检查一个目录是否存在。
   6 使用-e和!-e检查一个文件,目录或者软链接是否存在。
   7 使用-x和!-x检查一个文件是否为可执行文件。
正则表达式的一部分可以用圆括号,方便之后按照顺序用$1-$9来引用。

示例:


  1. if ($slow) { 
  2.   limit_rate  10k; 
  3.  
  4. if ($request_method = POST ) { 
  5.   return 405; 
  6.  
  7. if ($http_user_agent ~ MSIE) { 
  8.   rewrite  ^(.*)$  /msie/$1  break; 
  9.   
  10. if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) { 
  11.   set  $id  $1; 
  12.  
  13. if ($args !~ "post=140"){ 
  14.   rewrite ^ http://example.com/ permanent; 
  15.  
  16. if (!-f $request_filename) { 
  17.   break; 
  18.   proxy_pass  http://127.0.0.1; 
  19.   
  20. if ($invalid_referer) { 
  21.   return   403; 

注意:红色字符
注意:内置变量$invalid_referer用指令valid_referers指定。
  

2.5 rewrite


  1. 语法:rewrite regex replacement flag
  2. 默认值:none 
  3. 使用字段:server, location, if 
  4. 按照相关的正则表达式与字符串修改URI,指令按照在配置文件中出现的顺序执行
  5. 可以在重写指令后面添加标记。 

如果替换的字符串以http://开头请求将被重定向,并且不再执行多余的rewrite指令

尾部的标记(flag)可以是以下的值
  1  last - 完成重写指令,之后搜索相应的URI或location
  2  break - 完成重写指令,之后停止搜索
  3  redirect - 返回302临时重定向,如果替换字段用http://开头则被使用。
  4  permanent - 返回301永久重定向

注意:如果一个重定向是相对的(没有主机名部分),nginx将在重定向的过程中使用匹配server_name指令的“Host”头或者server_name指令指定的第一个名称,如果头不匹配或不存在如果没有设置server_name将使用本地主机名如果你总是想让nginx使用“Host”头,可以在server_name使用“*”通配符(查看http核心模块中的server_name)。例如:


  1. rewrite  ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  last; 
  2. rewrite  ^(/download/.*)/audio/(.*)\..*$  $1/mp3/$2.ra   last; 
  3. return   403; 

但是如果我们将其放入一个名为/download/的location中,则需要将last标记改为break否则nginx将执行10次循环并返回500错误


  1. location /download/ { 
  2.   rewrite  ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  break; 
  3.   rewrite  ^(/download/.*)/audio/(.*)\..*$  $1/mp3/$2.ra   break; 
  4.   return   403; 

//last 与 break 用来实现URI重写浏览器地址栏URL地址不变但是在服务器端访问的路径已经发生了变化
//redirect 与 permanent 用来实现URL跳转浏览器地址栏会显示跳转后URL地址
//last 与 break 是有区别的,last标记 在匹配后继续搜索而break 标记在匹配后则停止搜索
//因此,一般在根location中 (location /),或者直接写在server 标签中的rewrite 规则请使用last标记而在非根location中 (location /bbs/)请使用break标记。

如果替换字段中包含参数,那么其余的请求参数将附加到后面,为了防止附加,可以在最后一个字符后面跟一个问号


  1. rewrite  ^/users/(.*)$  /show?user=$1?  last; 


注意:大括号({和})可以同时用在正则表达式和配置块中,为了防止冲突,正则表达式使用大括号需要用双引号(或者单引号)
例如要重写以下的URL:
/photos/123456 
为:
/path/to/photos/12/1234/123456.png 
则使用以下正则表达式(注意引号):


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


如果指定一个“?”在重写的结尾,Nginx将丢弃请求中的参数,即变量$args,当使用$request_uri或$uri&$args时可以在rewrite结尾使用“?”以避免nginx处理两次参数串。
在rewrite中使用$request_uri将www.example.com重写到example.com:


  1. server { 
  2.    server_name www.example.com; 
  3.    rewrite ^ http://example.com$request_uri? permanent; 


同样,重写只对路径进行操作,而不是参数,如果要重写一个带参数的URL,可以使用以下代替:


  1. if ($args ^~ post=100){ 
  2.   rewrite ^ http://example.com/new-address.html? permanent; 


注意$args变量不会被编译,与location过程中的URI不同(参考http核心模块中的location)。


参考
URL重写模块(Rewrite)

结束
更多请:
linux 相关 37275208
vmware 虚拟化相关  166682360


本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/1004837