使用位置变量访问子文件夹和文件

使用位置变量访问子文件夹和文件

我正在尝试让 nginx 访问索引中每个目录列表末尾所add_after_body调用的文件。readme.php

对于每个子文件夹,readme.php可以存在另一个,它将被添加以替代文件夹结构根目录中存在的默认自述文件。如果不存在,则应使用根目录。

到目前为止我有以下代码:

location /archive/ {                                                        
    autoindex on;                                                           
    add_after_body /archive/readme.php;                                     
}  

这将强制将根自述文件用于 的所有子目录/archive/

我的下一步是访问内部自述文件,但我很难为其编写正确的正则表达式。我试过:

/archive/([^/])/
/archive/(.*/)
/archive/(.*)/

结合此代码:

# using /archive/([^/])/ as an example
location /archive/([^/])/ {                                                 
    autoindex on;                                                           
    add_after_body /archive/$1/readme.php;                                   
}

但是我的子目录继续使用根自述文件而不是它们自己的版本。

我已经在我的站点配置中以两种方式排序了这两个位置块,但似乎没有任何变化。

我知道对于第三步,我可以在位置块内使用 if 语句来检查文件是否实际存在,而不是盲目地尝试使用它,但我甚至无法检测到子文件夹......我该怎么办?

答案1

请注意,我对 nginx 一无所知,因此以下内容可能不正确。但是,我对正则表达式很了解,并且对配置文件有一些经验,所以我相信我可以提供帮助。

我假设您到目前为止已经研究过 nginx 文档,并且确信 nginx 引擎认为位置的形式是/dir/,而不是/dir。 如果这是错误的,则以下内容无效。

让我们首先看一下您的第二个正则表达式/archive/(.*/)。这可能不起作用,原因很简单,最好通过一个例子来解释。假设您有一个文件夹/archive/a/$1然后将是a//archive/$1/readme.php然后将是/archive/a//readme.php。我想您已经意识到了这个问题;您可以通过将结果字符串更改为来解决它/archive/${1}readme.php(请注意,这取决于正则表达式引擎的实现,使用哪个转义字符代替{},但如果没有特殊转义,1可能会被视为文件名的一部分而不是变量名)。

现在让我们分析一下第一种方法的问题。除非的每个直接子代都有一个恰好为一个字符长的名称,否则/archive/([^/])/这种方法将无法按预期工作。这是因为表示:“一个不是 的字符”。/archive[^/]/

为了解决这个问题,你可以将其更改为/archive/([^/]*)/(注意额外的*)。[^/]*意思是“除 之外的任意字符序列/”,或者换句话说,“直到下一个 的字符序列/”。

此时我们面临下一个问题:只有当 下只有一个嵌套级别时/archive,此方法才会起作用,即,如果所有子目录都采用 形式/archive/subdir/,则其中subdir不得包含/其自身。要解决此问题,您可以将正则表达式更改为类似/archive/(([^/]*/)*)(我将留给您来解释它 :-)) 的内容。

不幸的是,这个表达式会导致与第二个表达式相同的问题。尾随/将是 的一部分$1,并将导致//结果中的 ;您可以按照上面所述解决该问题(即通过类似 的方法/archive/${1}readme.php)。

您的第三种方法/archive/(.*)/可能会正常工作,但仅适用于 的子文件夹/archive/,即嵌套文件夹。就/archive/其本身而言,您有第一个代码片段,因此它应该可以正常工作。

既然没有,我相信还存在另一个问题:

在你的问题中,你给人的印象是你留下了第一个片段

location /archive/ {                                                        
    autoindex on;                                                           
    add_after_body /archive/readme.php;                                     
}

放置好第二个代码片段以下它。

但最终 nginx 引擎是一个“首次匹配”引擎:如果符合条件,则采取相关操作,并且不再考虑其余条件。

如果我对此是正确的,那么解决方案很简单:只需提出更具体的标准(即带有正则表达式的块)多于另一个。

最后一个想法与常见的正则表达式语法有关。我知道许多正则表达式引擎将其视为/特殊字符,如果要将其解释为文字,则必须对其进行转义。如果这适用于 nginx 正则表达式引擎,则必须更改正则表达式,将其替换/\/\通常情况下,提供转义字符)。由于我不了解 nginx,您必须自己找出答案 :-)

如果有帮助,请告诉我们。

相关内容