Forum Moderators: phranque

Message Too Old, No Replies

301 redirect from url with query string

Can't 301 redirect from dynamic pages. Please help!

         

Saurus Henry

12:08 pm on Sep 26, 2008 (gmt 0)

10+ Year Member



Hi there,

I'm working on a client's new website. The old website's product pages are all still indexed in google with good pagerank and rankings.

The old site's product pages were dynamic php pages which use a query string to determine which product is which.

They are formatted like this:
http://www.example.com/products/products_detail.php?news_id=0028

news_id being the product identifier.

I want to 301 redirect these pages to their new static product pages. I want widgetA's product page to redirect to widgetA's new product page, and widgetB's product page to redirect to widgetB's new product page.

My problem is this: 301 redirects don't take the string into account, only the filename. Therefore it will only redirect from the page products_detail.php, and not products_detail.php?news_id=0028

Every new product page is static.

I am trying to do this in .htaccess

If anyone can help me it would be greatly appreciated!

Many Thanks,
Henry

[edited by: Saurus_Henry at 12:10 pm (utc) on Sep. 26, 2008]

Saurus Henry

1:07 pm on Sep 26, 2008 (gmt 0)

10+ Year Member



Update:
Ok here's what I've done:
used mod_rewrite to redirect to an html page named the news_id
e.g. /products/0028.html
then created a 301 redirect from /products/0028.html to its new product page.
Here's my code:
***

php_flag session.use_trans_sid off
php_flag register_globals on
php_flag safe_mode off
php_flag open_basedir off
Options +FollowSymLinks

RewriteEngine On
rewritecond %{http_host} ^example.co.uk
rewriteRule ^(.*) http://www.example.co.uk/$1 [R=301,L]

rewriteCond %{QUERY_STRING} ^news_id=(.*)$
rewriteRule ^products/products_detail\.php$ /products/%1.html? [R=301,L] 

redirect 301 /products/0028.html http://www.example.co.uk/index2.php/cPath/0_76_84

***

Does anyone know how to condense it so that only one redirect takes place?
thanks!
H

[edited by: Saurus_Henry at 1:30 pm (utc) on Sep. 26, 2008]

jdMorgan

2:23 pm on Sep 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



DOn't mix mod_alias and mod_rewrite directives, as you cannot control which module which execute first. So, if you use mod_rewrrite at all, then use it for all.

To prevent sequential redirects and rewrites and to minimize unexpected problems, put you rules in order: External redirects first, ordered from most-specific to least-specific, followed by internal rewrites, again from most-specific to least-specific.

By 'specific' I mean 'selective'. That is, rules with more-specific patterns affecting the fewest number of URLs should generally go first, and the non-www-to-www domain redirect should almost always be the last external redirect.

Be sure to escape all literal periods within regex patterns by preceding them with a "\". Otherwise, the period is taken as a regex token meaning "match any single character."


RewriteEngine On
#
RewriteCond %{QUERY_STRING} ^news_id=(.+)$
RewriteRule ^products/products_detail\.php$ http://www.example.co.uk/products/%1.html? [R=301,L]
#
RewriteRule ^products/0028\.html$ http://www.example.co.uk/index2.php/cPath/0_76_84 [R=301,L]
#
RewriteCond %{HTTP_HOST} ^example\.co\.uk
RewriteRule (.*) http://www.example.co.uk/$1 [R=301,L]

One more thing: Do not consider yourself free to change anything about Apache directive syntax; Stick to the exact syntax and even character-casing seen in the documentation to avoid OS and server-version portability problems. Apache modules use very simple (so fast) parsers, and often cannot handle the variations in 'style' often seen in high-level coding and scripting languages.

Jim

g1smd

2:30 pm on Sep 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Are you sure that the second redirect shouldn't be a rewrite? Just comparing that with the original question. The second redirect exposes a "long and unfriendly" URL.

Note, also, the change on the very first RewriteCond, which now allows the redirect to happen even if extra/dummy parameters are present, and that those extra parameters are dumped during the redirect.

RewriteEngine On
#
RewriteCond %{QUERY_STRING} &?news_id=(.+)&?
RewriteRule ^products/products_detail\.php$ http://www.example.co.uk/products/%1.html? [R=301,L]
#
RewriteCond %{HTTP_HOST} ^example\.co\.uk
RewriteRule (.*) http://www.example.co.uk/$1 [R=301,L]
#
RewriteRule ^products/0028\.html$ /index2.php/cPath/0_76_84 [L]

g1smd

3:01 pm on Sep 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I created this example, from something I was working on recently. It includes a lot more fixes and might be worth studying in detail to understand what every part does.

You only have one parameter in the URL, so you can simplify this quite a bit:

External URL Format: www.example.com/345/1234567
Internal Server Path: /index.php?cat=345&art=1234567

# Specify acceptable index/root file. You could have a static
# index.html or allow index.php without parameters for root:
DirectoryIndex index.html index.php

# Redirect to remove trailing period or comma from URL request
# with parameters, such as from forum with autolink, and force
# www to always be in the URL:
RewriteCond %{QUERY_STRING} ^(([^&]+&)*)[.,]$
RewriteRule (.*) http://www.example.com/$1?%1 [R=301,L]

# Redirect to remove trailing period or comma from URL request
# with path, such as from forum with autolink, and force www:
RewriteRule ^(([^/]+/)*)[.,]$ http://www.example.com/$1 [R=301,L]

# Redirect two-parameter-based index.php¦html? or / URL request
# (with parameters in any order) to folder-based URL format, and
# force www to always be in URL:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.(php¦html?))?(\?[^\ ]*)\ HTTP/ [NC]
RewriteCond %{QUERY_STRING} &?cat=([0-9]{3})&?
RewriteCond %1>%{QUERY_STRING} ^([^>]+)>([^&]*&)*art=([0-9]{7})&?
RewriteRule ^(index\.(php¦html?))?$ http://www.example.com/%1/%3? [R=301,L]

# Force all remaining requests for named index files to drop
# the index file filename, and force www:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]*/)*index\.(html?¦php)(\?[^\ ]*)?\ HTTP/
RewriteRule ^(([^/]*/)*)index\.(html?¦php)$ http://www.example.com/$1 [R=301,L]

# General rule to force all non-www URLs to be www URLs.
# This rule must be the last one of the redirects:
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

# Rewrite such that stray parameters or value names on any index.html?
# or any index.php URL or on / URL request always fail to the
# 404 page:
RewriteCond %{QUERY_STRING} .
RewriteRule ^(index\.(php¦html?))?$ /this.page.does.not.exist [L]

# Rewrite URL request: www.example.com/345/1234567 to internal
# path: /index.php?cat=345&art=1234567 to serve content:
RewriteRule ^([0-9]{3})/([0-9]{7})$ /index.php?cat=$1&art=$2 [L]

Website now only directly responds with content as "200 OK" for paths like / and /345/1234567 and all other formats either redirect or fail to the 404 Error Page if a real file does not exist. It does this without having to do server-intensive !-d and !-f checks on the filesystem.

The site root can be implemented either as a static index.html page or by using index.php without any parameters. The script will also need to check that parameters are present, and that the values are acceptable, and fail to the internally script-generated 404 Error Page if not.

The rules in the .htaccess file restrict certain URL requests from ever reaching the filesystem on the server. They are redirected or failed to a 404 immediately.

[edited by: jdMorgan at 3:14 pm (utc) on Sep. 26, 2008]
[edit reason] Disabled graphic smile faces in code [/edit]