如何控制NGINX'Location'指令匹配顺序?

时间:2011-12-08 20:58:59

标签: nginx url-rewriting nginx-location

我正在尝试优化我的“位置”指令,但无法找到确定是否尝试过特定位置匹配的好方法。在位置块中使用echo对此没有帮助。

The NGINX ngx_http_core_module documentation有些令人困惑。

要使用正则表达式,必须使用前缀:

  1. ~用于区分大小写的匹配

  2. ~*用于不区分大小写的匹配

  3. 如何进行比赛:

    1. 具有与查询完全匹配的=前缀的指令。如果找到,搜索将停止。

    2. 所有剩余的指令与传统字符串。如果此匹配使用^~前缀,则搜索会停止。

    3. 正则表达式,按照在配置文件中定义的顺序。

    4. 如果#3产生匹配,则使用该结果。否则,使用#2的匹配。

    5. 这里的数字2表示“常规字符串”,但后来表示它可以与^~前缀一起使用。 ~不代表RegExp吗?如果没有,它如何确定什么不是RegExp?

      具体来说,我想要以下内容:

      1. 直接从文字/assets提供任何内容。停止搜索。

      2. 通过快速CGI停止搜索提供与RegExp \.php$|/$匹配的任何内容。

      3. 直接通过文字/

      4. 提供其他所有服务

        这样,对于从资源外部提供的非动态文件,只有/次匹配尝试。

        我有:

        location ^~ /assets {}      # search-terminating literal? or regex?
        location ~ \.php$|/$ {}
        location / {}               # is this match always attempted?
        

        从文档中看,实际的顺序似乎是1-3-2,始终运行文字/匹配。是的,这种优化不会对实际性能产生任何影响,但我只想澄清一些歧义。

1 个答案:

答案 0 :(得分:7)

来自维基:

location  = / {
  # matches the query / only.
  [ configuration A ] 
}
location  / {
  # matches any query, since all queries begin with /, but regular
  # expressions and any longer conventional blocks will be
  # matched first.
  [ configuration B ] 
}

所以,这将首先匹配: location ~ \.php$ {}

即使资产是由location / {}

提供的

在php块中你还希望在传递给fastcgi之前防范恶意上传:

if ($uri ~* "^/uploads/") {
  return 404;
}

正如您所看到的,nginx的工作方式与您预期的有所不同。