我在 Google 和 StackOverflow 上四处搜寻,试图找出我的问题,尝试了无数的解决方案,但没有一个完全奏效。
我希望将服务器上主域的 Web 根目录移动到子目录。目前我的网络根目录的服务器路径有什么:
/home/user/public_html/MyWebFilesHere
我想要什么:
/home/user/public_html/subdir/MyWebfilesHere
当我浏览到 mydomain.com 时,应该没有明显的差异(即重定向后“子目录”不可见)。
不幸的是,我仅限于纯粹使用 .htaccess 文件来执行此操作,因为我位于共享主机上并且无权访问 Apache 配置文件等。 :(
我目前在 public_html 的 .htaccess 中的内容是:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteRule ^(.*)$ /subdir/$1 [L]
这成功地将所有查询重定向到子目录,但是有一个非常奇怪的问题。如果我去
mydomain.com/Contact/
它工作得很好,将查询重定向到路径 /subdir/Contact / 但如果我去
mydomain.com/Contact
(注意缺少尾随“/”),地址栏中显示的内容
mydomain.com/subdir/Contact/
不是我想要的,因为显示了“subdir”
。在我的实际网站上,尝试浏览与
colincwilliams.com/Contact/
比较
colincwilliams.com/Contact
你们对如何在有或没有尾部斜杠的情况下默默地完成这项工作有什么想法吗?
I have dug high and low around Google and StackOverflow to try and figure out my problem, trying countless solutions but nothing has completely worked.
I'm looking to move the web root of the main domain on my server to a sub-directory. What I have currently for a server path to my web root:
/home/user/public_html/MyWebFilesHere
What I'm looking to have:
/home/user/public_html/subdir/MyWebfilesHere
When I browse to mydomain.com, there should be no visible difference though (i.e. "subdir" not visible after redirect).
Unfortunately, I am restricted to doing this purely with a .htaccess file since I'm on shared hosting and don't have access to Apache config files and such. :(
What I currently have in my .htaccess in public_html is:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteRule ^(.*)$ /subdir/$1 [L]
This successfully redirects all queries to the sub-directory, however there's a really weird issue. If I go to
mydomain.com/Contact/
it works great, redirecting the query to the path /subdir/Contact/ but leaving the address bar alone. If I go to
mydomain.com/Contact
(Note the lack of a trailing '/') though, what shows in the address bar is
mydomain.com/subdir/Contact/
which isn't what I want since "subdir" is showing.
For a working example on my actual site, try browsing to
colincwilliams.com/Contact/
compared with
colincwilliams.com/Contact
Do you guys have any ideas on how to make this work silently both with and without a trailing slash?
发布评论
评论(2)
发生这种情况可能是因为 mod_dir (如果对目录的请求缺少尾部斜杠,该模块会自动重定向浏览器到相同的内容和尾部斜杠。请参阅 mod_dir 中的 DirectorySlash 指令
发生的情况是:
mydomain.com/Contact
/Contact
不是目录/Contact
会被重写为/subdir /Contact
和内部重定向的/subdir/Contact
是一个目录并且缺少尾部斜杠,因此它重定向浏览器到mydomain.com/subdir/Contact/
您可以在 .htaccess 中添加
DirectorySlash off
来关闭。 mod_dir 来自重定向,但是如果您希望目录具有尾部斜杠,您可以为其添加单独的条件。根据您已有的内容,我们可以将其扩展为:注意:我将
!^/mydomain/
更改为!^/subdir/
,认为这是一个拼写错误,因为如果没有它,mod_rewrite 将无限期地在内部循环(foo -> /subdir/foo -> /subdir/subdir/foo -> /subdir/subdir/subdir/foo 等)。如果我错了,你可以改回来。编辑:请参阅我添加的 RewriteCond 与
\.(php|html?|jpg|gif|css) 匹配的内容
。这些是在不添加尾部斜杠的情况下传递的文件扩展名。您可以添加/删除以满足您的需要。This is probably happening because mod_dir (the module that automatically redirects the browser if a request for a directory is missing a trailing slash to the same thing with a trailing slash. See the DirectorySlash directive in mod_dir
What's happening is:
mydomain.com/Contact
/Contact
isn't a directory/Contact
gets rewritten to/subdir/Contact
and internally redirected/subdir/Contact
is a directory and missing the trailing slash so it redirects the browser tomydomain.com/subdir/Contact/
You can add
DirectorySlash off
in your .htaccess to turn off mod_dir from redirecting. But if you want directories to have trailing slashes, you can add a separate condition for it. Based on what you already have, we can expand it to this:Note: I changed
!^/mydomain/
to!^/subdir/
, figured it was a typo because without it, mod_rewrite would loop internally indefinitely (foo -> /subdir/foo -> /subdir/subdir/foo -> /subdir/subdir/subdir/foo, etc). If I got that wrong, you can change it back.Edit: See my additions of RewriteCond's matching against
\.(php|html?|jpg|gif|css)
. These are the file extensions that get passed through without getting trailing slashes added. You can add/remove to suit your needs.Jon Lin 的回答对于确定在我非常相似的设置中导致问题的原因非常有帮助。为了完整起见,我将包含他的回答中的相关信息:
,我的请求被重定向到
/subdir
,但有一些例外,并且不想通过允许 为每个例外重新启用 DirectorySlash。 RewriteEngine 在初始重定向到
/subdir
后继续,可以在 mod_dir 看到它之前模仿 mod_dir 的行为,同时也考虑到/subdir
。注意:如果有进一步的规则,您可能需要小心允许 RewriteEngine 继续。不匹配第二条规则将继续执行任何进一步的规则,这可能会产生不同的结果。
如果发生重定向到
/subdir
,可以通过使用第三条规则来停止 RewriteEngine 处理来避免这种情况:Jon Lin's answer was very helpful in determining what was causing the problem in my very similar setup. For completeness I will include the relevant information from his answer:
In my case, I had requests being redirected to
/subdir
with a few exceptions and didn't want to have to re-enable DirectorySlash for each of those exceptions.By allowing RewriteEngine to continue after the initial redirect to
/subdir
, it's possible to mimic what mod_dir would be doing while also taking/subdir
into account, before mod_dir gets to see it.Note: You may need to be careful about allowing RewriteEngine to continue if there are further rules. Not matching the second rule will continue on to any further rules which may produce a different result.
This can be avoided by using a third rule to stop RewriteEngine processing if the redirect into
/subdir
has happened: