开发者

Subtle htaccess problem. I am going insane

I want to have my primary domain be hosted from a subdirectory (have completed this step somewhat), i.e. when someone types in www.example.com/news behind the scenes it will go to www.example.com/subdirectory/news but will still show up as www.example.com/news.

I have used the following bluehost code to accomplish this:

RewriteEngine on

RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/subdirectory/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /subdirectory/$1

RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ subdirectory/index.php [L]

This code works if I type in www.example.com/news/ (notice the trailing slash) but does NOT work if I just type in 开发者_开发知识库www.example.com/news (without the slash). Any ideas why?

Thank you.


I think the problem is that after Apache rewrites /news to /subdirectory/news it then finds itself with a request matching a directory on the filesystem, which does NOT end in a trailing slash. So it issues a redirect to a new url including the trailing slash.

The thing is, we do actually want the traling slash to be added to preserve the canonical url (otherwise we end up with /news and /news/ leading to the same place - not good for relative links, SEO etc.), just not quite in the way apache is doing it. So we have to do it ourselves, by adding the following:

RewriteCond %{REQUEST_URI} ^/subdirectory/.*[^/]$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^subdirectory/(.*)$ /$1/ [L,R=301]

The conditions of this rule will match any requests that begin with 'subdirectory', DO match a directory on the fielsysem but do NOT end with a trainling slash. (e.g. '/subdirectory/news'). The rewriterule then issues a permanent redirect to the same path, but ending in a slash and with 'subdiretcory' stripped out (e.g. '/news/').

The client will then issue a request for '/news/', apache will rewrite this to /subdirectory/news/ and will not issue a redirect becuase it ends with a slash.

Quickly tested this out and it seems to do the trick.


Not really an answer to your question, but wouldn't it be easier to

  • Change your DocumentRoot to the public dir, or if you can't do that (e.g. on a shared host)...
  • Put the public files in your document root (public_html or whatever it's called) and the application files somewhere outside it (or if you cannot go above the document root, inside it but protected against web access with a Deny from all


andrewmabbott is right, and to fix it you need to use a ProxyPassReverse. This will rewrite all redirects to use the correct address.

The easiest way to do it would be something like:

ProxyPassReverse /subdirectory http://www.example.com/

However bluehost might have disabled mod_proxy, in which case this won't work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜