mod_rewrite seems to ignore a rule with a question mark? - .htaccess

I am trying to redirect
domain.com/page?user=something
to
domain.com/page/something
with
RewriteRule ^page?user=(\d[^/]+) /page/$1/ [R=301,L]
For some reason that's not working though. It seems to be just ignoring it even. When I go to domain.com/page?user=something nothing happens. mod_rewrite is enabled and all other rules are executing. I assume it could be due to the ? in the URL but I might be wrong?

You can use these 2 rules in your root .htaccess:
RewriteEngine On
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} /page(?:\.php)\?user=([^\s&]+) [NC]
RewriteRule ^ /page/%1? [R=302,L,NE]
# internal forward from pretty URL to actual one
RewriteRule ^page/([^/.]+)/?$ page?user=$1 [L,QSA,NC]

Related

301 redirect from URL with GET-parameters to the homepage

I have an old website with Joomla 1.5. It has some strange links with GET-parameters, like this:
http://www.primavista.ru/images/stories/catalog/?rand=1186511674
http://www.primavista.ru/images/stories/catalog/?rand=145388433
http://www.primavista.ru/images/stories/catalog/?rand=1553907057
http://www.primavista.ru/images/stories/catalog/?rand=1563973527
http://www.primavista.ru/images/stories/catalog/?rand=1981273478
http://www.primavista.ru/images/stories/catalog/?rand=2139631800
http://www.primavista.ru/images/stories/catalog/?rand=366928750
http://www.primavista.ru/images/stories/catalog/?rand=524689684
http://www.primavista.ru/images/stories/catalog/?rand=569077423
http://www.primavista.ru/images/stories/catalog/?rand=573405687
http://www.primavista.ru/images/stories/catalog/?rand=879649167
I want make redirect theses links to the homepage.
I tried some different instructions in .htaccess:
RewriteCond %{QUERY_STRING} ^/images/stories/catalog/?rand=([0-9]*)$
RewriteRule ^(.*)$ https://primavista.ru/? [R=301,L]
RewriteCond %{QUERY_STRING} ^/images/stories/catalog/?rand=(.*)$
RewriteRule ^(.*)$ https://primavista.ru/? [R=301,L]
RewriteCond %{QUERY_STRING} (^|&)(rand)=[^&]+ [NC]
RewriteRule ^images/stories/catalog(/.*)?$ https://primavista.ru/? [R=301,L,NC]
But no one not working. Maybe here someone can help me with this. Thanks
This probably is what you are looking for:
RewriteEngine on
RewriteCond %{QUERY_STRING} rand=\d+
RewriteRule ^/?images/stories/catalog/?$ / [R=301,L]
It is a good idea to start out with R=302 temporary redirections and to only change that to R=301 permanent redirections one you are satisfied with everything. That prevents nasty caching issues on the client side ...
UPDATE:
Your comment below indicates that you actually ask to remove the GET parameter in the redirected request, which you never mentioned before...
You can use the additional QSD flag for that:
RewriteEngine on
RewriteCond %{QUERY_STRING} rand=\d+
RewriteRule ^/?images/stories/catalog/?$ /? [R=301,QSD,L]

RewriteRule for 'pretty links' not working

I am trying to make a link that looks like https://www.exapmle.com/profile.php?u=8 to look like https://www.exapmle.com/profile/8
I have a tried variations of this in htaccess:
RewriteRule ^/profile/([0-9]+)/?$ profile.php?u=$1
RewriteRule ^/profile/([0-9]+)\.html /profile.php?u=$1
I don't know what i am doing wrong, the links don't change and I'm not getting any errors either
You may use this code in your site root .htaccess:
Options -MultiViews
RewriteEngine On
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} /profile\.php\?id=([^\s&]+) [NC]
RewriteRule ^ /profile/%1? [R=301,L]
# internal forward from pretty URL to actual one
RewriteRule ^/?profile/(\d+)(?:\.html)?/?$ profile.php?u=$1 [L,QSA,NC]

.htaccess redirect - two URLs with similar paths

So here's what I have.
www.website.com/foo (pretty URL to use on marketing pieces)
www.website.com/foobar (URL that actually exists on site)
I can get www.website.com/foo working perfectly with this:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /foo [NC]
RewriteRule ^ http://www.website.com/redirected/url-goes-here/ [L,R=301]
But that makes the www.website.com/foobar URL go there as well.
I'm sure this is a regex issue and I just don't know the correct symbol to get things working properly, but how can I make /foo redirect properly without effecting /foobar ?
Thanks.
Try this instead:
RewriteCond %{REQUEST_URI} ^/foo$ [NC]
RewriteRule ^ http://www.website.com/redirected/url-goes-here/ [L,R=301]
REQUEST_URI will get rid of the extra request headers that THE_REQUEST has. Then you can match the beginning and end of the requested URL with ^ and $.
You don't need the RewriteCond. Just be specific with the RewriteRule pattern
RewriteRule ^foo$ http://www.website.com/redirected/url-goes-here/ [L,R]
See more about regular expression.
Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.

SEO Url for Profiles

Preface
I'm trying to re-write a URL for a profile page. All of my application pages have a .html extension, so I'm trying to match just letters, numbers, -, and ..
So these would be valid
site.com/steve
site.com/steve-robbins
site.com/steve.robbins
But these wouldn't be
site.com/steve.html
site.com/steve-robbins.php
Assume I have a check in place so that custom URLs don't have .html or .php on the end.
Problem
I'm currently using this but it's not working
RewriteRule ^([a-zA-Z0-9\.-]+)$ profile.php?url=$1 [L]
It should set url to steve, but it's setting it to profile.php
What am I doing wrong?
My complete .htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*) http://www.%{HTTP_HOST}/$1 [R=301]
#
# LOGIN
#
RewriteRule ^([a-z0-9]{255})/activate\.html$ login.php?activate=$1 [L]
RewriteRule ^logout\.html$ login.php?logout [L]
#
# SETTINGS
#
RewriteRule ^change-([a-z]+)\.html$ account-settings.php?$1 [L]
RewriteRule ^([a-zA-Z0-9\.-]+)$ profile.php?url=$1 [L]
# SEO friendly URLs
RewriteRule ^([a-zA-Z0-9-_.]+)\.html$ $1.php [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([a-zA-Z0-9-_.]+)\.php
RewriteRule ^([a-zA-Z0-9-_.]+)\.php$ $1.html [R=301]
Add this to the top of your rules (under the RewriteBase / directive):
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
That should stop it from looping. The rewrite engine will keep re-applying all the rules until the URI going in (sans query string) is the same as the URI that comes out of the rules. That's why the value of url is profile.php.
I'm kind of a beginner in interpreting mod_rewrite rules but if I understand it correctly your rule is matched and than matched again, either add something to the url matching scheme like /profile/user or add a condition to not redirect if already redirected
Try adding a leading slash to the redirect like this:
RewriteRule ^([a-zA-Z0-9.-]+)$ /profile.php?url=$1 [L]
The reason you're getting a url value of profile.php is because the [L] flag is kinda misleading when it comes to the .htaccess file. In the server config files it does exactly what you'd think, but in the .htaccess file it stops reading rules at that rule, but then goes through the rules again until path is unchanged by any of the rules. By adding the leading /, your rule will not match the second time around as you exclude / from the regex. I spent a while struggling with this feature myself.

Htaccess non-www and strip index.php in a nice way

I'm having some trouble with my .htaccess redirections.
I want a situation in which the (non-www)domain.tld is redirected to the www.domain.tld. And I want to rewrite the arguments to skip the index.php, making a request for /foo go to index.php/foo.
Initial situation
First I had these rules
RewriteCond %{HTTP_HOST} ^domain\.tld [NC]
RewriteRule ^(.*)$ http://www.domain.tld/$1 [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_\ /:-]*)$ index.php [L]
And this worked. Mostly. What didn't work was that in PHP $_SERVER['PATH_INFO'] stayed empty and I disliked the whitelisting of the characters.
Change for PATH_INFO and to accept more
So I changed the last line into this:
RewriteRule ^(.*)$ index.php/$1 [L]
This fixed the PATH_INFO and the limited characters. However, I recently noticed that this caused the non-www redirect to www. to fail miserably.. When going to the non-www domain Apache says
Moved Permanently
The document has moved here.
Where 'here' is linked to the same thing I typed (non-www domain.tld) and thus failing to serve the user.
Continuing the search..
I found a lot of Q&A here and elsewhere or the topic of non-www redirections, but all seem to fail in some way. For example:
RewriteCond %{HTTP_HOST} !^www.*$ [NC]
RewriteRule ^/.+www\/(.*)$ http://www.%{HTTP_HOST}/$1 [R=301]
This just didn't do that much. Nothing got redirected, although the website was served on the non-www.
Anyone knowing what I do wrong or having a solution for this mess? :)
(Preferably, I would like the non-www redirection to be global. So that I don't have to change the actual domain name every time.)
I guess you’re just missing the L flag to end the rewriting process:
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
And make sure to put this rule in front of those rules that just cause an internal rewrite.

Resources