跳转至

Nginx rewrite指令


2013-03-26 by dongnan

举个栗子

下面的nginx配置文件有两个rewrite配置示例:

cat /etc/nginx/conf.d/default.conf

server    
{

    server_name test.com www.test.com;
    #... 其它配置项省略

    # 访问 test.com,301重定向到 www.test.com
    if ($host != 'www.test.com') {
        rewrite ^(.*)$ http://www.test.com$1 permanent;
    }

    location / {
        # 伪静态
        rewrite ^/$ /index.php?_c=index&_a=index last;
        rewrite ^/demo/(.*)/(.*)\.html$ /index.php?_c=$1&_a=$2 last;

    }

    #... 其它配置项省略
}

测试

使用curl命令测试 rewrite 规则:

curl -IL test.com
HTTP/1.1 301 Moved Permanently
Server: nginx
#...省略
Location: http://www.test.com/

HTTP/1.1 200 OK
Server: nginx
#...省略

返回结果中看到curl命令共请求了两次:

  • 第1次服务器返回301状态码 test.com被重定向新的Location: http://www.test.com/
  • 第2次访问新的地址是 www.test.com 返回200状态码 。

相对路径

需要说明的是rewrite正则表达式部分只对相对路径有效:

  • 如果你想匹配主机名(比如 test.com 参考上面例子),请与if指令、$host变量配合使用。
  • 如果你想匹配参数(比如id=1参考下面例子),请与if指令、$query_string变量配合使用。

什么是相对路径

http://www.test.com/demo?id=1 为例:

  • 主机名 www.test.com
  • 相对路径/demo
  • 参数?id=1

配置文件:

{
    #... 其它配置项省略

    if ($query_string ~* "id=(.+)$") {
        rewrite ^/ http://demo.com/so.php permanent;
    }
}

rewrite 指令

  • 语法: rewrite regex replacement flag
  • 默认值: none
  • 使用字段: server, location, if
  • 功能: 按照相关的正则表达式或者字符串来重写URI,rewrite指令按照在配置文件中出现的顺序执行,可以在重写指令后面添加需要的标记。

flag 标记:

  • last:完成重写指令,之后搜索相应的URIlocation
  • break:完成重写指令,之后停止搜索。
  • redirect:返回302临时重定向,浏览器地址栏会显示跳转后URL地址。
  • permanent:返回301永久重定向,浏览器地址栏会显示跳转后URL地址。

引用张宴老师的一段话:

  • lastbreak,用来实现URI重写,浏览器地址栏URL地址不变,但是在服务器端访问的路径已经发生了变化。
  • redirectpermanent,用来实现URL跳转,浏览器地址栏会显示跳转后URL地址。
  • lastbreak 是有区别的,last标记在匹配后继续搜索,而break标记在匹配后则停止搜索。

因此一般在根 location 中(即 location /{..}), 或者直接写在 server 标签中的 rewrite 规则使用last标记, 而在非根 location 中(比如 location /pic/{..})使用break标记。

注意:

  • 如果替换的字符串以http(s)://开头,请求将被301或者302 URL重定向,并且不再执行多余的rewrite指令。
  • 正则表达式的一部分可以用圆括号括起来,方便之后按照顺序用$1-$9来引用,例如上例中的$1$2引用方式。

if 指令

  • 语法: if (condition) { … }
  • 默认值: none
  • 使用字段: server, location
  • 功能: 判断一个条件,如果条件成立则后面的大括号内的指令将执行,相关配置从上级继承。

条件

条件可以是以下任意一个:

变量名称,不成立的值为: ""(空字符串)"或者一些用0开始的字符串。

  • 变量比较可以使用=(表示等于)或者使用!=(表示不等于)运算符。

正则表达式的模式匹配使用符号 ~*~

  • ~为区分大小写的匹配。
  • ~*不区分大小写的匹配(abc匹配ABC)。
  • !~!~*意为"不匹配的"。

测试目标 -f/-d/-e/-x

  • 使用-f!-f检查一个文件是否存在。
  • 使用-d!-d检查一个目录是否存在。
  • 使用-e!-e检查一个文件,目录或者软链接是否存在。
  • 使用-x!-x检查一个文件是否为可执行文件。

参考

Nginx location指令

回到页面顶部