如何在没有斜杠的情况下访问目录的 index.php 并且不获得 301 重定向

Posted

技术标签:

【中文标题】如何在没有斜杠的情况下访问目录的 index.php 并且不获得 301 重定向【英文标题】:How to access directory's index.php without a trailing slash AND not get 301 redirect 【发布时间】:2013-09-08 15:26:59 【问题描述】:

我有这个结构:site.com/api/index.php。当我将数据发送到site.com/api/ 时没有问题,但我想如果 api 也能在没有斜杠的情况下工作会更好,如下所示:site.com/api。这会导致 301 重定向,从而丢失数据(因为未转发数据)。我尝试了所有我能想到的重写并且无法避免重定向。这是我目前的重写规则(尽管它可能无关紧要)。

RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteRule ^api/(.*)$ api/index.php [L]

我可以在不使用尾部斜杠的情况下使此网址正常工作并维护帖子数据吗?

一些无效的重写:(仍然重定向)

RewriteRule ^api$ api/index.php [L] 
RewriteRule ^api/*$ api/index.php [L]

【问题讨论】:

尾部斜线由apache模块mod_dir添加:httpd.apache.org/docs/2.2/mod/mod_dir.html 另外,你的重写规则,它的编写方式,有尾部斜杠作为规则的一部分。您可能只需从规则中删除 / 即可。 对。我在想我可以将对该目录的请求重写为 index.php 以便模块永远不会启动,但它不起作用。我会更新以显示我在那里尝试过的内容。 这个 .htaccess 文件在哪里?它必须在 api 的父目录中。此外,!-d 条件可能必须被删除。这意味着如果请求的文件不是目录且/api 是目录,则条件将不匹配。 它在父目录中,没有条件我试过了。 【参考方案1】:

您首先需要关闭目录斜杠,但有一个原因为什么尾部斜杠非常重要:

Mod_dir docs:

关闭尾部斜杠重定向可能会导致信息泄露。考虑 mod_autoindex 处于活动状态 (Options +Indexes) 并且 DirectoryIndex 设置为有效资源(例如,index.html)并且没有为该 URL 定义其他特殊处理程序的情况。在这种情况下,带有斜杠的请求将显示 index.html 文件。但不带斜杠的请求将列出目录内容。

这意味着访问不带斜杠的目录只会列出目录内容,而不是提供默认索引(例如index.php)。所以如果你想关闭目录斜线,你必须确保在内部重写尾部斜线。

DirectorySlash Off

RewriteCond %REQUEST_FILENAME -d
RewriteRule ^(.*[^/])$ /$1/

RewriteCond %REQUEST_FILENAME !-f
RewriteRule ^api/(.*)$ api/index.php [L]

第一个规则确保尾部斜杠被附加到末尾,尽管只是在内部。与外部重定向浏览器的 mod_dir 不同,内部重写对浏览器是不可见的。下一条规则然后进行 api 路由,并且由于第一条规则,保证有一个尾部斜杠。

【讨论】:

这肯定是在启用模块时避免重定向的唯一方法吗? 另外,共享主机允许这种更改是否常见?我发现他们对某些类似的事情很严格。 @m59 mod_dir 的DirectorySlash 开启时无法避免重定向。您可以通过关闭重定向来避免重定向,但是 mod_dir 在 mod_rewrite 之前处理 URI(几乎总是),所以没有办法绕过它。我现在不知道托管服务对此有多严格。但是DirectorySlash 是“索引”覆盖的一部分,因此他们很可能允许这样做。 应该是^(.*[^/])$ $1/ 没有前导斜杠吗?前导斜线导致我访问上一个目录。 嗯。总是更复杂哈哈。我的项目需要是可移植的。我的 .htaccess 位于应用程序的根目录,但不是文档根目录(目前)。无论我在这里做什么,无论 app 文件夹是在文档根目录还是嵌套,它都必须保持功能。如果您想节省我弄清楚这一点的可怕时间,我将不胜感激,但如果我要求太多,我可以搞砸它!我猜我需要添加一个条件?【参考方案2】:

如果您不想使用 Jon Lin 提供的解决方案(重新配置所有指向目录的 URL),您可以使用以下代码(注意正则表达式中的 ? - 它基本上表示“api”后面的斜杠" 是可选的)。我还没有测试过,但它应该可以正常工作:

RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteRule ^api/?(.*)$ api/index.php [L]

【讨论】:

我确实尝试过。可选的斜线没有帮助,也不能完全删除斜线。 我很确定这是行不通的,因为模块会在重写有机会修复它之前启动并重定向。 @m59 我认为您之后被重定向的原因是因为您的浏览器缓存了 301 响应,因此它自动重定向到带有斜杠的 URL。你应该在 curl 或新的浏览器中测试

以上是关于如何在没有斜杠的情况下访问目录的 index.php 并且不获得 301 重定向的主要内容,如果未能解决你的问题,请参考以下文章

在这种情况下,GNU为什么要关心斜杠?

网络资源路径的双斜杠//和双反斜杠\的区别

linux下安装了apache,如何设置默认首页文档?

URL最后结尾反斜杠(/)加与不加区别

当 url 没有斜杠时,AWS s3 强制 302 重定向 - 需要 301s

IIS 重定向在没有斜杠的情况下无法正常工作