Forum Moderators: phranque

Message Too Old, No Replies

htaccess stop appending redirect to url

htaccess appends redirect to the destination url

         

marlowesoft

4:47 pm on Feb 15, 2010 (gmt 0)

10+ Year Member



Hi,
I am moving some sites from static html to dynamic CMS.
Currently I use a set of htaccess redirect rules like this :-

Redirect 301 /old.html http://www.example.com/newsite/old/

(yes that is ment to be a slash at the end of the url!)
but what I have noticed is that my browser is redirected to :
http://www.example.com/newsite/old/?old.htm
I can't figure out how to stop the '?old.htm' bit being appended to the URL.
(the new URLs dont always match the original html file names so I need to create a seperate rule for each page)

Any help would be great

Thanks

Matt

jdMorgan

6:29 pm on Feb 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I assume that you're requesting "old.html" with a query string appended to it.

If so, use mod_rewrite instead of mod_alias, and put a "?" on the end of the substitution URL to clear the originally-requested query string.

Order your rewriterules with external redirects first, in order from most-specific to least-specific, followed by all internal rewrites, again in order from most-specific to least-specific.

Do not mix the use of mod_alias 'redirect' directives and mod_rewrite directives; doing so, can cause unexpected results because your directives are processed in per-module order, and not necessarily in the order that you write them in your config files.

Jim

marlowesoft

7:13 pm on Feb 15, 2010 (gmt 0)

10+ Year Member



I'm not requesting old.html with anything appended :(
Typing this address into browser :-
http://www.example.com/old.html

redirects me to :
http://www.example.com/newsite/old/?old.html

Could you give me an example of your sujestion for mod_rewrite ?
I had tried something like this (deleted the entry so might not have it down corectly)
RewriteRule /old.html http://www.example.com/newsite/old/
but that still appended '?old.html'

Thanks

Matt

g1smd

7:29 pm on Feb 15, 2010 (gmt 0)

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



Put a "?" on the end of the substitution URL in the rule to clear the originally-requested query string.

marlowesoft

8:24 pm on Feb 15, 2010 (gmt 0)

10+ Year Member



Ok, have tried the following :-
redirect /old.html http://www.example.com/newsite/old/?
and I get back
http://www.example.com/newsite/old/?

have also tried :
RewriteRule /old.html http://www.example.com/newsite/old/?
and I get a 404 page not found (but still have http://www.example.com/old.html in the address bar)
and evan tried :-
RewriteRule ^/old.html /newsite/old/?
and got a 404 page not found with that as well (http://www.example.com/old.html still in the address bar)

Now I know i'm missing something very simple here, but cant see the wood for the tree's!

jdMorgan

10:34 pm on Feb 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



How do you explain the appearance of "?old.html" on the URL?

You likely have some other code in .htaccess or in a server config file that is rewriting that URL, and thus violating both of the "rules" I posted above: Do not mix mod_alias with mod_rewrite, and put your mod_rewrite rules in the given order.

You must find this other code, tell us what it's for (what does it do on and for *your site*), and possibly post it.

These kinds of problems are not particularly difficult to fix, given enough information...

Jim

marlowesoft

9:12 am on Feb 16, 2010 (gmt 0)

10+ Year Member



Yup, just relised what you ment, we have the following :
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ [%{HTTP_HOST}...] [R=301,L]

# BEGIN Expression Engine Rewrite

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteRule ^(.*)$ /index.php?$1 [L]
</IfModule>
# END Expression Engine Rewrite

redirect /old.html http://www.example.com/newsite/old/
redirect /shorturl http://www.example.com/news/mon/am/

# Header Expires

# 480 weeks
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=290304000, public"
</FilesMatch>

# 2 DAYS
<FilesMatch "\.(xml|txt)$">
Header set Cache-Control "max-age=172800, public, must-revalidate"
</FilesMatch>

# 2 HOURS
<FilesMatch "\.(html|htm)$">
Header set Cache-Control "max-age=7200, must-revalidate"
</FilesMatch>

<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "public"
Header set Expires "Fri, 10 Apr 2020 20:00:00 GMT"
</FilesMatch>


the redirect rules are used for 301'ing old pages and short urls

The problem is I have been landed with trying to sort this out with no documentation on how it was originally setup :(
From what you have said I presume the conflict is with the index.php?$1 rewrite and the redirect, so how can I convert the redirects to rewrites and ensure they are run in the correct order?

Again thanks for the help :)

Matt

jdMorgan

4:44 pm on Feb 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Since you have mixed mod_alias and mod_rewrite, it is impossible to determine whether your internal rewrite to ExpressionsEngine will precede the redirects invoked by the Redirect directives or follow them. If the internal rewrites run first, then the following redirects will indeed 'expose' the internal paths to the client.

As I stated above, re-code those Redirect directives to RewriteRules, and then place them *before* your domain canonicalization redirect: Redirects go first, most-specific to least-, then internal rewrites, again most-specific to least, [L] flag on all rules.

Do that, and there's an excellent change your problem will simply go away.

Jim

[edited by: jdMorgan at 10:22 pm (utc) on Feb 16, 2010]

marlowesoft

6:05 pm on Feb 16, 2010 (gmt 0)

10+ Year Member



Thanks :)
That got it working!
Just in case anyone come accross this posting the end result was this :-

# ^ = match start of URL
# $ = match end of URL
# [R] = Do a redirect with new URL (rather than hiding the new URL)


RewriteEngine On
RewriteRule ^old.html$ http://www.example.com/new/page [R]
RewriteRule ^shorturl$ http://www.example.com/path/to/long/url/
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ [%{HTTP_HOST}...] [R=301,L]

# this adds trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [R=301,L]

# BEGIN Expression Engine Rewrite

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteRule ^(.*)$ /index.php?$1 [L]
</IfModule>


Thanks again guys :)

Matt

g1smd

9:35 pm on Feb 16, 2010 (gmt 0)

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



# [R] = Do a redirect with new URL (rather than hiding the new URL)


R gives a 302 redirect.

R=301 will give a 301 redirect.

As for 'hiding the new URL', these words are meaningless. A rewrite takes a URL request and fetches content from a different server-internal filepath. There's no *URL* involved *inside* the server.

URLs are used on the web and filepaths are used inside the server. These two things are not the same, but are merely 'associated' by the action of the server software accepting a URL request and then fetching content from a filepath on the hard drive.

jdMorgan

11:49 pm on Feb 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Several needed corrections/optimizations:

RewriteEngine on
#
# Redirect specific URLs
RewriteRule ^old\.html$ http://www.example.com/new/page [R=301,L]
RewriteRule ^shorturl$ http://www.example.com/path/to/long/url/ [R=301,L]
#
# Redirect to add a trailing slash if the slash is missing, no filetype is appended
# to the URL-path, and the requested URL-path does not resolve to an existing file
RewriteCond $1 !^([^/]*/)*[^.]*\.[a-z0-9]+$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ http://www.example.com/$1/ [R=301,L]
#
# Redirect to force canonical "www" subdomain
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
#
# Expression Engine Rewrite - with turbo boost(tm) by jdm@WebmasterWorld
RewriteCond $1 !^index\.php$
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?$1 [L]

By avoiding or deferring "file- and directory-exists" checks, your server performance will be improved.

By including correct and meaningful comments, your future-frustration level will be improved.

Redirect types are all specified, all rules end with "[L]".

Jim