如何使用.htaccess重写将根URL重定向到子目录?

280

尝试获取

www.example.com

直接跳转到

www.example.com/store

我尝试了多个代码片段,但都没有起作用。

我尝试过的内容:

Options +FollowSymlinks
RewriteEngine on

RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

RewriteCond %{HTTP_HOST} ^(.+)\www.example\.com$
RewriteRule ^/(.*)$ /samle/%1/$1 [L]

我做错了什么?

19个回答

305
你可以使用一个重写规则,使用^$表示根目录,并将其重写为你的/store目录,像这样:
RewriteEngine On
RewriteRule ^$ /store [L]

5
如果 /store 是一个物理子目录,那么您需要在 RewriteRule 的替换部分添加一个斜杠作为结尾。否则,mod_dir 将触发一个 301 外部重定向以添加斜杠,并且 /store/ 将暴露给您的用户。此外,如果您在根目录中有 DirectoryIndex 文档(例如 index.html),那么正则表达式 ^$ 将不会“似乎”匹配(没有任何“看起来”的情况),因为 mod_dir 会在初始重写之后对索引文档发出内部子请求。为了解决这两个问题,请将其更改为 RewriteRule ^(index\.html)?$ /store/ [L] - MrWhite
如果您可能在以后的某个日期添加一个真实页面到根级别,您应该使用临时重定向,将[L]替换为[R=302,L] - digitalacorn

186

我很惊讶没人提到这个:

RedirectMatch ^/$ /store/

基本上,它将重定向根URL,只有根URL。

答案来源于此链接


这是简单而且迄今为止最好的答案。 - iamnabink
1
@iamnabink 这取决于你想要一个内部重写(如问题所述和之前的回答所述)还是一个302临时外部重定向(如此处所述)。这也取决于您是否有现有的mod_rewrite指令,正如OP明确所示。因此,在问题的上下文中,这不是"最佳答案"。 YMMV。 - MrWhite
如果您无法访问服务器配置文件,请在Web应用程序根目录下的.htaccess文件中添加此行(例如/var/www/html_docs/.htaccess)。否则,您可以修改服务器配置,请参见https://httpd.apache.org/docs/2.4/mod/mod_alias.html#redirectmatch。 - Dio Phung

118

试试这个:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteRule ^$ store [L]
如果您想要进行外部重定向(使访问的浏览器显示重定向后的URL),请在此处设置R标志:
RewriteRule ^$ /store [L,R=301]

6
做得很好。sample.com和www.sample.com都重定向到www.sample.com/store,这正是我想要的。谢谢Gumbo以及所有回答的人。阅读你们的回复,我学到了很多,并感谢反馈。 - AlphaSmith
1
我很好奇,这个重定向后会显示www.example.com作为URI吗?如果不是,应该如何更改? - stefmikhail
1
♦ - 为什么您的解决方案比下面的Sander更好呢?我注意到您的最后一行是相同的,但如果只需要这个,为什么要包括“RewriteCond”和第一个“RewriteRule”呢? - stefmikhail
@Gumbo,你能否看一下http://stackoverflow.com/questions/17937873/how-to-remove-a-subdirectory-from-the-url-when-forwarding-to-sudirectory这个问题吗? - Starx
天啊,经过几天的尝试,“RewriteRule ^$ web [L]” 成功将我的Symfony根目录(http://www.example.com/agenda)重定向到其web子文件夹,其中包含app.php的DirectoryIndex (http://www.example.com/agenda/web/[etc])。我很想去掉这个web,但需要再努力一天。 - cdsaenz
显示剩余4条评论

82

这是我用来重定向到子目录的方法。它以隐形的方式实现并仍然允许通过与现有文件或其他内容相匹配的请求。

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?site.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /subdir/$1
RewriteCond %{HTTP_HOST} ^(www.)?site.com$
RewriteRule ^(/)?$ subdir/index.php [L]

将 site.com 和 subdir 替换为您的值。


42

1
如果您需要一个对用户不可见的重定向,那么这个答案非常有效。 - Fred

26

如果您想重写URL并隐藏原始URL,另一种选择是:

RewriteEngine on
RewriteRule ^(.*)$ /store/$1 [L]

使用此功能,如果您例如键入http://www.example.com/product.php?id=4,它将透明地打开位于http://www.example.com/store/product.php?id=4的文件,但不会向用户显示完整的URL。

3
如果您希望将查询字符串传递到重写后的URL中,请在“[L]”后面添加“QSA”(查询字符串追加)(“[L, QSA]”)。 - devios1
@chaiguy谢谢你的提示,但在我的服务器上,它没有使用QSA也能正常工作(但我同意附加QSA可能更好)。也许这是因为我的Apache服务器有一些特殊的配置? - gaborous
1
这个方法对我来说,example.com 透明地显示 example.com/store 的内容,但是 example.com/test 重定向到 example.com/store/test,显示 URL。 - Geoffrey Hale
1
@devios1 在这个例子中,您不需要使用QSA标志,因为在_substitution_字符串中没有查询字符串。当_substitution_中没有查询字符串时,默认情况下会传递请求的原始查询字符串。 - MrWhite
1
除非您还在“/store”子目录中有另一个包含mod_rewrite指令的“.htaccess”文件(因为默认情况下不会继承mod_rewrite指令,从而防止重写循环),否则此示例将导致重写循环(500错误响应)。 - MrWhite
在这个例子中,使其重定向而不更改URL的关键片段是什么?我一直以为我需要一个代理来做到这一点。这是如何工作的? - Martin Braun

16

这似乎是最简单的解决方案:

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$
RewriteRule (.*) http://www.example.com/store [R=301,L]

使用其他解决方案时,我遇到了重定向循环。


11
大多数上述解决方案都是正确的,但它们都缺少重定向的透明度。
在我的情况下,当访问www.example.com时,我想要被重定向到子目录/store,但不更新URL为www.example.com/store。 (我所想要的只是从该目录获取页面代码)。 如果这也是你的情况,下面的解决方案完美地解决了这个问题。
RewriteEngine on
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ /store/$1 [L]

来源: http://wiki.dreamhost.com/Transparently_redirect_your_root_directory_to_a_subdirectory

将根目录透明地重定向到子目录
当您在DreamHost上有多个域名时,有时可能需要将根目录指向站点的子目录。例如,如果您想在example.com上运行WordPress,但希望WordPress实际上位于example.com/blog中,则可以使用此方法轻松完成。
以下说明了如何使用.htaccess文件将根目录转发到子目录。请注意,此过程不涉及移动任何文件或更改任何代码,而是通过服务器配置进行操作。


我尝试将最后一行更改为RewriteRule ^(.*)$ http://otherpage.com/subfolder/$1 [L],但它会更新URL。 - steps
你所需要做的就是替换 examplestore 这两个词。 - Mahmoud Zalt
我没有解释得很清楚。我拥有 example.comotherpage.com 域名。当我访问 example.com 时,我希望显示来自 otherpage.com/subfolder 的内容,而不更新 URL。 - steps
好的,我的上面的回答并没有解决这个问题。请尝试发布一个新的问题。 - Mahmoud Zalt

8
我不理解你的问题...
如果你想将每个请求重定向到一个子文件夹:
RewriteRule ^(.*)$ shop/$1 [L,QSA]

http://www.example.com/* -> wwwroot/store/*

如果您想要重定向到一个包含域名的子文件夹
RewriteCond %{HTTP_HOST} ([^\.]+\.[^\.]+)$
RewriteRule ^(.*)$ %1/$1 [L,QSA]

http://www.example.com/* -> wwwroot/example.com/*

我喜欢你的代码 ([^\.]+\.[^\.]+)$ 用于将域名保留为子文件夹名称。 - eQ19

7

我发现为了避免循环重定向,将重定向的范围限制在根目录内非常重要。

我会使用以下代码:

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$
RewriteRule (.*) http://www.example.com/store [R=301,L]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接