homepage Welcome to WebmasterWorld Guest from 54.204.58.87
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
htaccess rewrite - the trailing slash
GymGuy




msg:4074736
 4:17 am on Feb 5, 2010 (gmt 0)

Hello I’m using htaccess to rewrite my domain’s URL. However i’m completely stuck!

Htaccess calls the php page with the following URL:
http://www.example.com/index.php?levelone=yyy&leveltwo=zzz

The following input urls will resolve:
http://www.example.com/yyy/zzz/
http://www.example.com/yyy/zzz
http://www.example.com/yyy/

However the following URL gives a 404:
http://www.example.com/yyy

I plan to have php detect and add missing trailing slashes when the page data exists in the database, redirecting with a 301. If no page data exists in the database, php will give a 404 header.

I can append the URL with the missing trailing slash within htaccess , however the page then goes through a two-step process where there’s a 301 redirect to the error page and then a 404 header is given:

http://www.example.com/yyy [301 -> ]

http://www.example.com/yyy/ [404 -> ]

http://www.example.com/yyy

If I have php detect and add missing trailing slashes then I can cut out the 301 redirect.

Any ideas on how I fix the issue with the url ‘http://www.example.com/yyy'? I assume i'm overlooking something simple in my htaccess file but just can't see it!

Any better way to do this?

I would be grateful if anyone can help!



The htaccess file is follows:
-------------------------------------
#exclusions
RewriteRule ^(sitemap\.xml|robots\.txt|favicon\.ico) - [L]

#block list
IndexIgnore *

#rewrite url
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^([^/]*)/$ /?levelone=$1&leveltwo=$2 [L]
RewriteRule ^([^/]*)/([^/]*)/$ /?levelone=$1&leveltwo=$2 [L]
RewriteRule ^([^/]*)/([^/]*)$ /?levelone=$1&leveltwo=$2 [L]

#canonicalization:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1/ [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://www.example.com/ [R=301,L]

#hotlinks:
RewriteEngine on
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?example\. [NC]
RewriteCond %{HTTP_REFERER} !google\. [NC]
RewriteCond %{HTTP_REFERER} !search\?q=cache [NC]
RewriteCond %{HTTP_REFERER} !msn\. [NC]
RewriteCond %{HTTP_REFERER} !yahoo\. [NC]
RewriteCond %{REQUEST_URI} !^/images/warning\.gif$
RewriteRule \.(gif|jpg|png)$ /images/warning.gif [NC,L]

 

jdMorgan




msg:4074756
 5:42 am on Feb 5, 2010 (gmt 0)

Your rules are in the wrong order.

Put all external redirects first, ordered from most-specific to least-specific. Most-specific rules affect one or only a few URLs, as exemplified by your "index.php" canonicalization rule. Least-specific is the catch-all non-canonical domain redirect.

BTW, that rule could do with some improvement. If you don't use any subdomains other than www, then the following is a much more robust solution:

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

It also avoids adding a trailing slash to all requests -- a possible contributor to your declared problem.

Follow your external redirects with all of your internal rewrites, again from most-specific to least-specific.

The variable $2 in your first internal rewrite rule above is undefined; Omit the "&leveltwo=$2" query part, or give "leveltwo=" a hard-coded value.

You can replace internal rewrites two and three with a single rule by making the trailing slash optional:
RewriteRule ^([^/]*)/([^/]*)/?$ /?levelone=$1&leveltwo=$2 [L]

Only one "RewriteEngine on" is needed. It must precede any other mod_rewrite directives.

One comment on your narrative. mod_rewrite will be far easier to understand if you keep in mind that it either performs a URL-to-URL translation (external redirect), or it does a URL-to-filepath translation (internal rewrite.) Therefore, the statement, "Htaccess calls the php page with the following URL: ..." is incorrect, as .htaccess merely translates a request for the URL www.example.com/yyy/zzz/ into a request for the file at "/index.php" with a query string of "levelone=yyy&leveltwo=zzz".
It's much easier to understand what's going on in mod_rewrite if you keep URLs and filepaths as two completely separate and distinct concepts.

One final comment: Adding slashes to 'page' URLs is generally a mistake, although doing so may be required by some CMS packages. URLs with trailing slashes are generally assumed to refer to directory indexes or to index pages in directories (my statement above about URLs versus filepaths notwithstanding). If it is an option and your site is not already well-linked, well-indexed, and well-trafficked, drop the trailing slashes from 'page' URLs instead of adding them.

Jim

GymGuy




msg:4075040
 6:24 pm on Feb 5, 2010 (gmt 0)

Brilliant! Thank you so much.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved