views:

330

answers:

1

I'm trying to use RewriteRules in .htaccess with relative paths, but Apache seems to want to output the physical path instead of the server path whenever I try to output a relative path. Absolute and server-root paths work fine. For example:

RewriteEngine On

# this works fine, 127.0.0.1/ab redirects to 127.0.0.1/cd
RewriteRule ^ab$ /cd [R]

# this doesn't work... 127.0.0.1/wx redirects to 127.0.0.1/C:/path/to/files/yz
RewriteRule ^wx$ yz [R]

Adding a "RewriteBase /" solves the problem, but it's tedious to add the path to every .htaccess, and it makes it harder to change the directory structure. Is there a reason RewriteBase defaults to the current physical path instead of the current URI path?

+2  A: 

It's because of the [R] which means the server will redirect to the new path (so the user's browser will issue a new request with the newly sent uri) instead of translating internally the URI to a local path.

In your first RewriteRule, there is an slash in the new path, thus the server doesn't try to translate it to the local path, but in the second rule, there is no slash, this is why it redirects to a complete local path. This explains too why it works with the RewriteBase set.

Either remove the [R] (you can replace it by a [L] in your case, this avoids the server trying to match other rules once it found a matching one), or add a slash before "yz" in your second RewriteRule.

I'd suggest to simply replace the [R] with a [L]: this way, the user won't see the rewritten path, which is generally what RewriteRules intend to do (mainly for SEO purposes), unless you specifically want to redirect your users to a new URL.

FWH
I do want an actual redirect to the new path -- I'm using this to create shortcut URLs and correct typos. Is there any way to avoid setting RewriteBase manually in every .htaccess file?
zildjohn01
In general you don’t need to change the `RewriteBase`. Just use relative paths for internal and absolute paths for external redirects.
Gumbo
Could you please illustrate what you mean? In my code I did use a relative path for an internal redirect, and it ended up with the undesirable behavior I described.
zildjohn01