在.htaccess中使用否定的正则表达式条件重写Cond不起作用?

7rfyedvj  于 2022-11-16  发布在  其他
关注(0)|答案(5)|浏览(150)

我试图阻止,在这个例子中是WordPress,重写某些URL。在这个例子中,我试图阻止它处理uploads目录中的请求,而是把这些请求留给服务器的404页面。所以我假设这和添加规则一样简单:

RewriteCond %{REQUEST_URI} !^/wp-content/uploads/

这个规则应该评估为false,并使规则链对那些请求失败,从而停止重写。但是没有......也许我需要在我的表达式中匹配cover和完整的字符串?

RewriteCond %{REQUEST_URI} !^/wp-content/uploads/.*$

不,也不是这样。所以在挠头之后,我做了一个正常的检查。也许实际的模式有什么问题。所以我做了一个简单的测试用例。

RewriteCond %{REQUEST_URI} ^/xyz/$

在这种情况下,当且仅当请求的URL是/xyz/,并且对于任何其他页面显示服务器的404页面时,重写才会发生。这正是我所期望的。所以我将插入一个!来否定该模式。

RewriteCond %{REQUEST_URI} !^/xyz/$

现在我希望看到与上述情况完全相反的情况。重写不应该发生在/xyz/上,而是发生在其他所有可能的URL上。相反,重写发生在每个URL上,包括/xyz/和其他URL。
所以,要么在Apache中,RewriteConds中使用了否定的正则表达式,要么是我不理解它的基本原理,是哪一个呢?
服务器是Apache 2。
文件全文:

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteBase /
RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/wp-content/uploads/
RewriteRule . /index.php [L]
</IfModule>

WordPress的默认文件加上我的规则。

2eafrhcq

2eafrhcq1#

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteBase /
RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_URI} !^/wp-content/uploads/ [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /index.php [L]
</IfModule>
gmxoilav

gmxoilav2#

所以,在经历了很多烦恼之后,我总算找到了问题所在。事实证明,我最初的问题中的规则确实起到了它应该起到的作用。其他一些方法也起到了同样的作用,比如

RewriteRule ^wp-content/uploads/.*$ - [L]

(Mark如果模式匹配,则规则为最后一个)或

RewriteRule ^wp-content/uploads/.*$ - [S=1]

(Skip如果模式匹配,则返回下一个规则)以及问题中的否定规则,如前所述。所有这些规则都工作得很好,并且在不重写的情况下将控制返回给Apache。
问题发生在这些规则被处理之后。相反,问题是我删除了一个默认的404.shtml,403.shtml等模板,我的主机提供。如果你没有任何.htaccess重写,这就工作正常;服务器将提供它自己的默认404页面,一切正常。(至少我是这么想的,但实际上是双重错误“此外,在尝试使用ErrorDocument处理请求时遇到了404 Not Found错误。”)
另一方面,当您有一个.htaccess时,它会对404页面执行第二次。如果页面在那里,它就会被使用,但是现在,对404.shtml的请求被catch-all规则捕获并重写为index.php。因此,我在这里或其他地方得到的所有其他建议,因为404页面最终被重写为index.php。
所以,解决的办法就是简单地恢复错误模板。回想起来,删除它们是相当愚蠢的,但我有这种“从头开始”的心态。不希望任何看似不必要的东西躺在周围。至少现在我明白了发生了什么,这是我想要的。
最后对塞西尔作了一个评论:我从来没有想过禁止访问任何东西,只是阻止重写的发生。现在并不是说这有多重要,但我只是想澄清这一点。

pieyvz9o

pieyvz9o3#

如果/wp-content/uploads/确实是请求的URI路径的前缀,则您的规则应该按预期工作。
但是,由于它显然不起作用,因此请尝试不匹配完整URI路径的路径前缀,而只匹配没有上下文每个目录路径前缀的剩余路径,如果.htaccess文件在文档根目录中,则匹配没有前导/

RewriteCond $0 !^wp-content/uploads/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .+ /index.php [L]

如果这两种方法都不起作用,那么使用mod_rewrite的日志记录特性来深入了解它的重写过程肯定会有所帮助。发出请求并查看用RewriteLog指定的日志文件中的条目。rewrite处理您的请求,并且当RewriteLogLevel大于或等于4时,您还将看到%{REQUEST_URI}等变量的值。

ve7v8dk2

ve7v8dk24#

我发现很多这样的例子,当采取“WordPress第一”的方法。例如,添加:
ErrorDocument 404 /error-docs/404.html
到.htaccess文件中会处理消息(“另外,出现404 Not Found错误...”)。

ds97pgxw

ds97pgxw5#

我在Drupal站点中尝试做同样的事情时遇到了这个问题,但是对于WP来说可能是一样的,因为它都是通过index.php完成的old-domain.org/my_path_to_ignore:

RewriteCond %{REQUEST_URI} !^/my_path_to_ignore$
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{HTTP_HOST} ^old-domain\.org$ [NC]
RewriteRule ^(.*)$ http%{ENV:protossl}://new-domain.org/$1 [L,R=301]

相关问题