apache - Apache htaccess 将根和所有根文件夹重写到子文件夹而不重定向
问题描述
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteRule ^$ /subdir/ [L,NC]
我想在不更改浏览器中的 URL 的情况下将根域重写为子文件夹。上面的代码仅适用于根域,但不适用于任何文件夹和文件。
例如,我有https://example.com/
和https://example.com/subdir/
。
将上面的代码放在.htaccess
文件中,当我去的时候,https://example.com/
我看到其中的内容https://example.com/subdir/
是好的。
但是当我去https://example.com/test.txt
我应该看到https://example.com/subdir/test.txt
但我得到了在此服务器上找不到请求的 URL。
当我https://example.com/abc
期待看到的内容时也会发生同样的情况https://example.com/subdir/abc
任何的想法?
解决方案
RewriteRule ^$ /subdir/ [L,NC]
将其更改为:
RewriteRule !^subdir/ subdir%{REQUEST_URI} [L]
任何未启动/subdir/
的请求都会在内部重写为/subdir/<url>
. REQUEST_URI
服务器变量包含完整的 URL 路径(包括斜杠前缀)。
我从替换字符串中删除了斜杠前缀,因为您已经定义了RewriteBase /
. (尽管这里两者都不是绝对必要的。)
更新:
...当我去的时候,
example.com/s
我被重定向到example.com/subdir/s/
s
是一个子文件夹subdir
,这有什么区别吗?
是的,如果/s
是子目录,那么 mod_dir 将在尾部斜杠(以“修复”URL)后附加外部 301 重定向。此重定向发生在 URL 被重写之后/subdir/s
- 从而暴露了/subdir
子目录。
为了处理这种情况,我们可以在现有重写之前添加另一个规则(重定向),首先检查请求是否会映射到/subdir
子目录中的目录,如果省略则附加斜杠(在 mod_dir 将斜杠附加到重写的 URL 之前)。
例如:
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/subdir%{REQUEST_URI} -d
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}/ [R=301,L]
这表明......对于任何请求:
!\.\w{2,4}$
- 不包含(看起来像)2 到 4 个字符的文件扩展名(假设您的目录不是这样命名的)!/$
- 并且当前不以斜线结尾。-d
- 并作为物理目录存在于/subdir
子目录中。- 然后重定向以在原始请求上附加斜杠
虽然这可能应该是 301(永久)重定向,但您应该首先使用 302(临时)重定向进行测试以避免潜在的缓存问题。
您需要在测试之前清除浏览器缓存,因为错误的 301 重定向 from /s
to/subdir/s/
将被浏览器缓存。
一个潜在的优化是删除文件系统检查并简单地假设任何不包含文件扩展名的请求都应该映射到一个目录。(但这取决于您是否以任何其他方式处理这些 URL。)
概括
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
# If the requested URL exists as a directory in "/subdir" then append a slash
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/subdir%{REQUEST_URI} -d
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}/ [R=301,L]
# Rewrite everything to "/subdir"
RewriteRule !^subdir/ subdir%{REQUEST_URI} [L]
推荐阅读
- php - 基于元素值的 Laravel 过滤器数组
- flutter - 为什么每当我将流添加到流控制器时,我的 then() 永远不会被调用?
- sql-server - 如何使用联合查询消除零
- google-sheets - 谷歌表格:帮助!我可以在不打开迭代计算的情况下解决循环依赖吗?
- html - 如何在文件路径中使用 id?
- java - JMS 消息路由器 - 变量(int 和 double)处理
- oim - OIM 12.2.1.3.0:如何为特定用户集或最终用户隐藏目录项(应用程序实例/角色)
- jquery-ui-datepicker - jQuery UI-Datepicker 禁用所有星期日,除了 1 个特定的星期日
- pandas - 复杂数据集的下采样问题
- reactjs - 如何仅在模态加载时获取数据