Brett
Brett

Reputation: 20049

Rewriting URL and making new URL show in location bar

I'm using the below code to rewrite some URL's:

RewriteEngine On
Options +FollowSymlinks
RewriteBase /
RewriteRule ^New_Hampshire/[a-zA-Z0-9_+\-\s]*\.html$ NH/

Keep in mind that there is also this rule below that..

RewriteRule ^([a-zA-Z]{2})/ state.php?state=$1 [L]

Now, what I am wanting to achieve is if someone goes to for example:

www.mydomain.com/New_Hampshire/index.html

I want the location bar to show:

www.mydomain.com/NH/

Usually I am able to achieve this by using the [R] flag at the end, however in this instance it doesn't work, which I am guessing it may have something to do with the secondary rule.

Is this possible to do?

Also, how can I change this so that it also redirects:

www.mydomain.com/New_Hampshire/

As you can see the above doesn't contain an index.html reference.

Lastly, if I wanted to make these 301 redirects, would I just do something like..

RewriteRule ^New_Hampshire/[a-zA-Z0-9_+\-\s]*\.html$ NH/ [R=301]

Upvotes: 4

Views: 1372

Answers (1)

danielv
danielv

Reputation: 3107

You need to understand the difference beween URL rewrite (achieved in your case by Apache's mod_rewrite) and redirect, which is part of the HTTP spec and achieved by sending a standard HTTP header and status code to the client (browser).

With URL rewrite, when a request is processed by the web server, you have an option to map a requested URL sent by the client, to a local resource represented by a different local path. This is done for various reasons like being able to present clean and short URLs to a user, hide the internal structure of the resources on the server, protecting certain resources etc.

The browser usually doesn't know a URL was re-written by the server (unless there is some other indication) and will still display the original requested URL in the address bar. It is not possible to manipulate the client's requested URL remotely without the client knowing about it.

HTTP redirect, on the other hand is part of the HTTP spec and is a way to tell the client that the requested URL can be found in a different location. The web server does this by sending a "Location" header with the redirected URL and an HTTP status code that tells the client what happened. There are several 30x status codes for this, with the most commonly used are 301 for telling the client that the resource was permanently moved and should be addressed by the new URL from now on and 302 for telling the browser that the resource was found but temporary resides under a new URL (Apache's implementation uses 302 by default when you specify the R flag in the rule).

The client will receive an HTTP response with the new location and the status code and issue a new HTTP request to the new URL. It will also replace the location in the address bar if this is the main request (i.e. not a sub request to a resource like an image or script).

See http://httpd.apache.org/docs/current/rewrite/flags.html#flag_r

Note that Apache's documentation advises to use the L flag with the redirection flag (e.g. [R, L] or [R=301, L]) or you can get unexpected results (because it will continue to process the following rules). This is probably why your R flag doesn't work.

So, you can do something like this (just an example):

RewriteRule ^New_Hampshire.* NH/ [R=301, L]

This will redirect the client from any /New_Hampshire prefix (with or without the *.html) URL, to NH/ and change the address bar.

Then the next rule:

RewriteRule ^NH/? state.php?state=NH [L]

Or more generic:

RewriteRule ^([a-zA-Z]{2})/? state.php?state=$1 [L]

This will catch the NH (or other state) URL and rewrite it to the proper actual resource (state.php).

BUT, this is just an example to show you the rules. You probably need to handle the logic in the first rule. Because something needs to map the full states' names (New_Hampshire) to the shortcuts (NH), unless you want to write a rule for each state.

Upvotes: 3

Related Questions