Evik James
Evik James

Reputation: 10503

How to rewrite this URL to a redirect page?

I am using Microsoft-IIS/7.5 on a hosted server (Hostek.com)

I have an existing site with 2,820 indexed links in Google. You can see the results by searching Google with this: site:flyingpiston.com Most of the pages use a section, makerid, or bikeid to get the right information. Most of the links look like this:

flyingpiston.com/?BikeID=1068
flyingpiston.com/?MakerID=1441
flyingpiston.com/?Section=Maker&MakerID=1441
flyingpiston.com/?Section=Bike&BikeID=1234

On the new site, I am doing URL rewriting using .htaccess. The new URLs will look like this:

flyingpiston.com/bike/1068/
flyingpiston.com/maker/1123/

Basically, I just want to use my htaccess file to direct any request with a "?" question mark in it directly a coldfusion page called redirect.cfm. On this page, I will use ColdFusion to write a custom 301 redirect. Here's what ColdFusion's redirect looks like:

<cfheader statuscode="301" statustext="Moved Permanently">
<cfheader name="Location" value="http://www.newurl/bike/1233/">
<cfabort>

So, what does my htaccess file need to look like if I want to push everything with a question mark to a particular page? Here's what I have tried, but it's not working.

RewriteEngine on
RewriteRule ^? /redirect.cfm [NS,L]

Update. Using the advice from below, I am using this rule:

RewriteRule \? /redirect/redirect.cfm [NS,L]

To try to push this request

http://flyingpiston2012-com.securec37.ezhostingserver.com/?bikeid=1235

To this page:

http://flyingpiston2012-com.securec37.ezhostingserver.com/redirect/redirect.cfm

Upvotes: 0

Views: 1677

Answers (1)

Peter Boughton
Peter Boughton

Reputation: 112220

There's a couple of reasons what you're trying isn't working.

The first one is that RewriteRule uses a regex, and ? is a regex metacharacter, which therefore needs be escaped with a backslash (\?) to tell it to match the literal question mark character.

However, the second part of the problem is that the regex for RewriteRule is only tested against the filename part of the URL - it specifically excludes the query string.

In order to match against the query string you need to use the RewriteCond directive, placed on the line before the rule (but applied in between the RewriteRule matching and replacing), acting as an additional filter. The useful bit is that you can specify which part of the URL to match against (as well as having the option for using non-regex tests).

Bearing all this in mind, the simplest way to match/rewrite a request with a query string is:

RewriteCond %{QUERY_STRING} .
RewriteRule .* /redirect/redirect.cfm

The %{QUERY_STRING} is what the regex is tested against (everything in CF's CGI scope can be used here, and some other stuff too - see the Server Variables box in the docs).

The single . just says "make sure the matched item has any single character"

At the moment, this rule will preserve the existing query string - if you want to discard it, you can place a ? onto the end of the replacement URL. (If you need to use a query string on the URL and not discard the old version, use the [QSA] flag.)

In the opposite direction, you're losing the filename part of the URL - to preserve this, you probably want to append it onto the replacement as PATH_INFO, using the automatic whole-match capture $0.

These two things together provides:

RewriteCond %{QUERY_STRING} .
RewriteRule .* /redirect/redirect.cfm/$0?

One final thing is that you'll want to guard against infinite loops - the above rule strips the query string so it will always fail the RewriteCond, but better to be safe (especially if you might need to add a query string), which you can do with an extra RewriteCond:

RewriteCond %{QUERY_STRING} .
RewriteCond %{REQUEST_URI} !/redirect/redirect\.cfm
RewriteRule .* /redirect/redirect.cfm/$0?

Multiple RewriteCond are combined as ANDs, and the ! negates the match.

You can of course add whatever flags are required to the RewriteRule to have it behave as desired.

Upvotes: 2

Related Questions