【问题标题】:.htaccess not rewriting existing files.htaccess 不重写现有文件
【发布时间】:2021-08-26 12:49:36
【问题描述】:

我正在尝试通过 php 文件路由所有请求并检查登录名和权限来限制对我网站某个部分的访问。

我有一个文件夹 (/doc),其中包含各种 .html 文件,使用 mod_rewrite 我将所有有效文件重定向到根目录中的 .php 文件(现在只打印一个测试字符串)。

这是我的 .htaccess:

# BEGIN WordPress
# Le direttive (linee) tra `BEGIN WordPress` e `END WordPress` sono
# generate dinamicamente, e dovrebbero essere modificate solo tramite i filtri di WordPress.
# Ogni modifica alle direttive tra questi marcatori verrà sovrascritta.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
 RewriteCond %{REQUEST_URI} !/(wp-content/uploads/.*)$
 RewriteCond %{REQUEST_URI} !/(doc/.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
RewriteCond %{HTTP_HOST} ^mywebsite\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.mywebsite\.com$
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^webmail$ "https\:\/\/mywebsite\.mywebsite\.com\:2096\/" [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^doc/(.*)$ /dl-file.php?file=$1 [QSA,L]

最后两行应该将所有有效文件的 URL 重写为 php 文件。

发生的情况是文件夹 (mywebsite.com/doc/) 可以正常工作,我不明白为什么。而对于.html 文件(mywebsite.com/doc/index.html),它只显示它们而不加载.php

【问题讨论】:

  • 您可能正在查看早期尝试的缓存结果...
  • 上移最后一条规则,将其置于RewriteBase 行下方
  • 指令的顺序肯定是错误的(“webmail”规则可能没有做任何事情),但是,“最后一条规则”应该仍然工作,它是“最后的”。但是,不应将其移至 RewriteBase 行下方...正如上面的评论所述(法语),您不应手动编辑 # BEGIN WordPress# END WordPress 评论标记之间的代码,因为 WordPress 将覆盖它(至少尝试)。你还有这个问题吗?您是否确认这不是缓存问题?
  • 我还想问为什么您不只是将/doc/... 的每个请求都重写到您的脚本,而不仅仅是物理文件。您的脚本应该已经确定请求是否映射到可下载文件,因此应该能够处理 404 等。
  • @MrWhite 这不是缓存问题,我已经清理了缓存,尝试了隐身模式、其他浏览器、智能手机。我已经上下移动了 RewriteRule,删除了 RewriteCond,似乎没有任何效果。对于不存在的文件,我会重定向到我的 .php 文件,而现有文件会立即获取服务器...

标签: apache .htaccess mod-rewrite


【解决方案1】:

这不是缓存问题,我已经清理了缓存,在隐身模式下尝试过 模式,其他浏览器,智能手机。我已将 RewriteRule 向上移动并 下来,删除了 RewriteCond,似乎没有任何效果。对于不存在的 文件我得到重定向到我的 .php 文件,而现有文件只是 立即获取服务器...

忽略您在当前指令中有文件检查(即%{REQUEST_FILENAME} -f)这一事实(因此不应将不存在的文件定向到您的 PHP 脚本,除非您请求错误的 URL 或您在测试)...

看起来您可能有一个前端代理(可能是 Nginx?)来提供静态文件?这是一个相对常见的设置,但这意味着您的应用程序服务器 (Apache) 完全被静态文件请求绕过,因此您的指令甚至不会被直接文件请求处理。

在不调整前端代理的情况下,我可以将文件移动到不同的目录,但保持 URL 不变,并使用 Apache 来检查此文件的存在,而不是请求的 URL . (或者,更改您的网址。)

例如,您可以将文件移动到 /actual-files 子目录(或理想情况下位于文档根目录上方的某个位置*1)。因此,对/doc/myfile.html 的请求实际上是指/doc/actual-files/myfile.html,但由于/doc/myfile.html 实际上并不存在,因此前端代理不会触及它。

# Block direct access to `/doc/actual-files/`
RewriteRule ^doc/actual-files - [F]

# Rewrite "/doc/file" requests to download script
RewriteCond %{DOCUMENT_ROOT}/doc/actual-files/$1 -f
RewriteRule ^doc/(.*)$ /dl-file.php?file=$1 [QSA,L]

但是,您将需要更改指令的顺序,并且应避免手动更改 # BEGIN WordPress 部分中的代码。

所以,这就变成了……

# Block direct access to `/doc/actual-files/`
# >>> BUT PROXY SERVER WILL STILL HAVE ACCESS (*1)
RewriteRule ^doc/actual-files - [F]

# Redirect HTTP to HTTPS here...

# Rewrite "/doc/file" requests to download script
RewriteCond %{DOCUMENT_ROOT}/doc/actual-files/$1 -f
RewriteRule ^doc/(.*)$ /dl-file.php?file=$1 [QSA,L]

# Webmail (website.website.com???)
RewriteCond %{HTTP_HOST} ^(www\.)?mywebsite\.com$
RewriteRule ^webmail$ "https://mywebsite.mywebsite.com:2096/" [R=301,L]

# Prevent certain directories being routed through WordPress
RewriteCond %{REQUEST_URI} /wp-content/uploads/ [OR]
RewriteCond %{REQUEST_URI} /doc/
RewriteRule ^ - [L]

# BEGIN WordPress
# Le direttive (linee) tra `BEGIN WordPress` e `END WordPress` soon
# generate dinamicamente, e dovrebbero essere modificate solo tramite i filtri di WordPress.
# Ogni modifica alle direttive tra questi marcatori verrà sovrascritta.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

除此之外:在重写下载脚本之前,您需要确保请求通过 HTTPS(当前在您的配置中缺失)。

*1 将文件移动到公共子目录仍将允许代理服务器直接访问这些文件(如果用户找到了真正的文件系统路径)。为避免此“安全问题”,您需要将文件移动到文档根目录上方 - 公共 HTML 空间之外。

【讨论】:

  • 如果我尝试通过 .htaccess 隐藏 403 后面的文件,我可能有这个“前端代理”这一事实使它毫无用处,对吧?
  • @Xruik 是的。正如我上面提到的,理想情况下,这些文件需要移动到文档根目录之上。或者,正如我最初建议的那样,将它们移动到“私有”子目录 - 但这取决于安全性。 (或者,调整前端代理,为这个子目录做一个例外。)
  • @Xruik 你确认有前端代理了吗? (您可以通过查看这些静态文件请求之一的 HTTP 响应标头来判断。)
  • 是的,“server: nginx”出现在标题中,就是这样!谢谢!
  • 就像对其他人的评论一样,我发现在我的托管 (SiteGround) 中我可以停用缓存(NGINX 直接交付)。
猜你喜欢
  • 2014-09-03
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 2015-12-25
相关资源
最近更新 更多