Reputation: 102
So I'm no .htaccess expert, by no means, but I have managed to put this code together for a webiste I'm making:
Options -Indexes +Includes
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteRule ^\.htaccess$ - [F]
RewriteRule ^$ /%{ENV:BASE}/index.php?id=home
RewriteCond %{REQUEST_URI} !\.php$ [NC]
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]
RewriteRule ^([a-zA-Z0-9]*)$ /%{ENV:BASE}/index.php?id=$1 [QSA,L]
</IfModule>
It basically changes www.example.com/some/dir/index.php?id=home
to www.example.com/some/dir/home
while the first few rules are creating some kind of relative path value so I don't have to change the RewriteBase everytime I change the base folder (this is important for this project!).
It works perfectly fine, but now I have encountered a problem where there have to be spaces in the URL like www.example.com/some dir/sub folder/home
and this messes everything up.
If you click a link on the page (e.g. "href="home"
") it redirects to www.example.com/home
instead of www.example.com/some dir/sub folder/home
with a 404 error, obviously (even though it works if there are no spaces!). I found out if right click > "copy link to clipboard" it becomes the encoded version www.example.com/some%20dir/sub%20folder/home
even if it shows the decoded version in the address bar. BUT if you manually type the decoded version www.example.com/some dir/sub folder/home
it still works fine.
There seems to be a problem with spaces and encoding. How do I get my hyperlinks working properly?
-- EDIT --
Thanks to the tutorial posted by elcodedocle, I simply added backslash space: ^([a-zA-Z0-9/ ]*)$
to the regex in the last rule, even if it's not the best method. Then I noticed the [L]
flag in the second last rule. I removed it because this shouldn't be the last rule (don't know why it was there in the first place...) and now it works! Well, kind of...
Now, If there is a trailing slash at the end of the URL it sill doesn't work anymore. Probabply because of the removal of the [L]
flag in the rule but I don't know how to fix this...
Upvotes: 2
Views: 316
Reputation: 784878
Have your .htaccess like this:
Options -Indexes +Includes -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteCond %{REQUEST_URI} !\.php$ [NC]
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ %{ENV:BASE}$1 [R=302,L,NE]
RewriteRule ^\.htaccess$ - [F]
RewriteRule ^$ /%{ENV:BASE}/index.php?id=home [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?)/?$ %{ENV:BASE}index.php?id=$1 [QSA,L]
</IfModule>
This is working fine under all the test cases you have described in your question like handling spaces, trailing slashes etc.
Upvotes: 2
Reputation: 8484
Try changing:
RewriteRule ^([a-zA-Z0-9]*)$ /%{ENV:BASE}/index.php?id=$1 [QSA,L]
to
RewriteRule ^([a-zA-Z0-9%]*)$ /%{ENV:BASE}/index.php?id=$1 [QSA,L]
(It's a wild guess but it's the only one of your rules that has problems with %
)
[EDIT] Unencoded spaces are not allowed in URIs. The ban on spaces is enforced by all browsers as they will convert every space to %20
before sending the request via the http protocol. A workaround to handle them in mod_rewrite is described on this tutorial:
Since URLs can't have spaces (except as %20), use underlines or hyphens to replace them. If you ABSOLUTELY have to use spaces (%20) in your URIs, you can include them in your regex within a range definition as {space}, i.e., ([a-zA-Z\ ]+). However, this is NOT advised.
[EDIT2] If that doesn't work, you may have to translate %20
into spaces, then apply the other rules. Here is a hack based on this answer you may try:
sedspace.sh
:
#!/bin/sh
sed -u 's/%20/ /g'
.htaccess
:
...
RewriteMap sed-space prg:sedspace.sh
RewriteRule ^(.*)$ ${sed-space:$1}
...
(Make sure that sedspace.sh is executable)
Upvotes: 1