ModRewrite: QUERY_STRING not redirecting - apache

I have the following rewrite rules in place:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^manufacturer=&
RewriteRule (.*) $1? [R=410,L]
But it doesn't seem to work. I'm trying to redirect with URL's like
http://www.example.com/?manufacturer=someone to http://www.example.com/ and page.php?manufacturer=someone to page.php
What am I doing wrong?
EDIT:
I have mod_rewite enabled and AllowOverride All in my site config
The above code is in the .htaccess file

The query string ^manufacturer=& only matches manufacturer parameters that are empty and it also requires that the equals sign is followed by an ampersand which doesn't seem to be your wanted behaviour.
By the way, you do realize the status code 410 means that the resource is Gone (indicates that the resource requested is no longer available and will not be available again)?
You seem to want to redirect back to the current page without the query parameter, so I suggest using a 302 or 301 redirect instead.
Try this:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^manufacturer=.+$
RewriteRule .* $0? [R=301,L]

Related

.htaccess RewriteRule from long url to show short url

Im trying to rewrite url from long to short but cant wrap my head around this.
My survey rewrite works wonderfully but after completing my survet php redirects to www.example.com/survey_thank_you.php?survey_id=1
but I would like to show url like www.example.com/thank_you
Im not even sure if this is possible.
Im new with .htaccess and i have tried almost everthing
.htaccess
Options +FollowSymLinks
Options -MultiViews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^survey_thank_you.php?survey_name=([0-9a-zA-Z]+)/?$ Thank_you [L,NC,QSA]
RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name=$1 [L,NC,QSA] #works like charm.
Any help or directions will be highly appreciated.
Solution:
Options +FollowSymLinks
Options -MultiViews
RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^survey_id=([0-9a-zA-Z]+)/?$
RewriteRule ^survey_thank_you\.php$ /%1/thank_you [R,L,QSD]
RewriteRule ^([0-9a-zA-Z]+)/thank_you$ survey_thank_you.php?survey_id=$1 [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name=$1 [L,NC,QSA]
but after completing my survet php redirects to www.example.com/survey_thank_you.php?survey_id=1
You need to "correct" the URL that PHP is redirecting you to after the survey. If the desired URL is /thank_you (or /Thank_you?) then PHP should be redirecting to that URL.
You then use mod_rewrite in .htaccess to internally rewrite /thank_you back into the URL that your application understands. ie. /survey_thank_you.php?survey_id=1. However, therein lies another problem, where does the 1 (survey_id) come from in the query string? Presumably you don't want to hardcode this? So this would need to passed in the requested URL. eg. /1/thank_you or perhaps /thank_you/1?
However, is this really necessary? The resulting "thank you" page is not a page that should be indexed or a page that is normally navigated to by the user, so implementing a user-friendly URL here doesn't seem to be a worthwhile exercise?
RewriteRule ^survey_thank_you.php?survey_name=([0-9a-zA-Z]+)/?$ Thank_you [L,NC,QSA]
RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name=$1 [L,NC,QSA] #works like charm.
You are using a survey_name URL parameter (referencing an alphanumeric value) in your directives, but a survey_id ("numeric"?) URL parameter in your earlier example? So, which is it? Or are these rules unrelated?
You state that the second rule "works like charm", but how? What URL are you requesting? That would seem to rewrite /Thank_you to survey_form.php?survey_name=Thank_you - but that does not look correct?
As mentioned in comments, the RewriteRule pattern matches against the URL-path only. To match against the query string you need an additional condition that matches against the QUERY_STRING server variable. This would also need to be an external 3xx redirect, not an internal rewrite (in order to change the URL that the user sees). Therein lies another problem... if you don't change the URL that your PHP script is redirecting to then users will experience two redirects after submitting the form.
You also need to be careful to avoid a redirect loop, since you are internally rewriting the request in the opposite direction. You need to prevent the redirect being triggered after the request is rewritten. ie. Only redirect direct requests from the user should be redirected.
So, to answer your specific question, it should be rewritten something like this instead:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^survey_name=[0-9a-zA-Z]+/?$
RewriteRule ^survey_thank_you\.php$ /Thank_you [QSD,R,L]
The check against the REDIRECT_STATUS environment variable ensures that only direct requests are processed, not internally rewritten requests by the later rewrite. REDIRECT_STATUS is empty on the initial request and set to the string 200 (as in 200 OK status) after the first successful rewrite.
The QSD flag (Apache 2.4) is necessary to discard the original query string from the redirect response.
So the above would redirect /survey_thank_you.php?survey_name=<something> to /Thank_you.
But this is losing the "survey_name" (or survey_id?), so should perhaps be more like the following, in order to preserve the "survey_name":
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^survey_name=([0-9a-zA-Z]+)/?$
RewriteRule ^survey_thank_you\.php$ /%1/Thank_you [QSD,R,L]
Where %1 is a backreference to the value of the survey_name URL parameter captured in the preceding CondPattern.
However, you would then need to modify your rewrite that turns this back into an understandable URL.
(But you should probably not be doing this in the first place without first changing the actual URLs in the application.)

htaccess rewrite rule from folder to folder with querystring

I am looking to include a rewrite rule for the following but can't seem to get it to work. I don't want to pass any query string in but I need to add one to the rule.
I want this URL:
https://example.co.uk/vehicles/
to point to:
https://example.co.uk/search-results/?category=1
but keep the first URL in the address bar.
I need to pass in a variable called category with a value.
I tried the following but it didn't work for me:
rewriterule ^vehicles/$ search-results/?category=1 [NC, L]
Any help would be appreciated.
RewriteEngine On
RewriteRule .* ? [F,L]
RewriteRule ^(.*)$ https://example.co.uk/$1 [R,L]
RewriteRule ^ad/(.*/)?([0-9]+)$ view-ad/?ad=$2 [NC,L]
RewriteRule ^vehicles/$ search-results/?category=1 [NC,L]
I managed to solve it. It was due to an Ajax load on the page.
Glad you solved your initial query, however, the following two directives in your posted .htaccess file will break your site, so presumably, these have already been removed?
RewriteRule .* ? [F,L]
RewriteRule ^(.*)$ https://example.co.uk/$1 [R,L]
The first directive simply blocks all access to your site, returning a 403 Forbidden response. And the second directive will result in a redirect loop.
Now that it works is it possible to have another rewrite rule that does this https://example.co.uk/vehicles/?something=1 and rewrite to https://example.co.uk/vehicles/?category=1&appendsomething=1 but only display https://example.co.uk/vehicles/
I assume you mean https://example.co.uk/search-results/?category=1&something=1 (as opposed to /vehicles/) - where something=1 is appended on the end of the query string?
You wouldn't be able to make this "display as https://example.co.uk/vehicles/" - as this would conflict with your existing (working) directive.
However, you could potentially modify your existing directive to handle requests for /?something=1 and pass this through to the substitution. This would simply require the addition of the QSA flag (Query String Append). For example:
RewriteRule ^vehicles/$ search-results/?category=1 [QSA,NC,L]
The QSA flag results in the query string from the request being appended to the end of the query string specified in the RewriteRule substitution.
UPDATE: To redirect HTTP to HTTPS, you would need something like the following instead:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.co.uk/$1 [R,L]
Note the preceding RewriteCond directive - this ensures that only HTTP requests are redirected, not everything (HTTP and HTTPS), so avoiding a redirect loop. Ultimately this should also be a 301 (permanent) redirect, so you should change R to R=301, but only when you are sure it's working OK.

Opencart 301 Redirects

Having a problem with redirect in a .htaccess file on an Opencart store.
It seems that any URL with /index.php?_route_= isn't getting redirected.
For example, this works:
redirect /old-url-here http://example.com/new-url?
This doesn't:
redirect /index.php?_route_=some-url.asp http://example.com
Any idea or suggestions as to what might get this to work?
You can't match against the query string using mod_alias' Redirect directive. You'll need to use mod_rewrite, and if you use mod_rewrite, you're probably going to want to stop using mod_alias altogether.
Try:
RewriteEngine On
RewriteCond %{QUERY_STRING} route=some-url\.asp
RewriteRule ^index\.php$ http://example.com/
Another thing is - apart from Jon's answer - that URLs like index.php?_route_=some-keyword are used/created only internally and only in case you have the SEO turned on. In this case, you click on a link with URL like http://yourstore.com/some-keyword and this URL is rewritten into index.php?_route_=some-keyword.
Therefore you shouldn't be creating URLs like that on your own nor try to redirect from them. If you need to redirect, catch the first SEO URL to redirect it.
We do not know where did you put your changes into the .htaccess file, but if you take a close look at this rewrite rule
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
not only you'll find out it is the last rule there, but it also has this L switch which is telling Apache server that if this rule is matched, do a URL rewrite(, attach the query string [QSA] and) stop matching other rules [L] - this is the Last one.
If you need to redirect only a specific URL, do it the same way as redirect for sitemap.xml is done (for example) and place it before the last rewrite rule:
RewriteEngine On
RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
# ...
# your new rule here - while the URL in the link is http://yourstore.com/some-url.asp
RewriteRule ^some-url.aspx$ index.php?route=some-folder/some-controller [L]
# ...
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

Using a .htaccess to RewriteRule and Redirect 301 at the same time?

I have a couple of specific URLs that I want to display differently on my website. For example I want "/contact.php" to become "/contact". So I added this to my .htaccess:
RewriteRule ^contact$ contact.php
And to avoid having 2 different URLS pointing to the same page, I also want to do a 301 redirect between the old URL and the new one:
Redirect 301 /contact.php http://www.example.com/contact
Each of the line above works well separately. But if I add them both in my htaccess, I have a redirect loop. How can I fix that?
In the end, if I either type "/contact" or "/contact.php", I want to see the contact page with the url "/contact".
Edit: I also tried things like that, and it doesn't work:
RewriteRule ^/contact\.php$ http://www.example.com/contact [R=301,L]
RewriteRule ^/contact$ /contact.php [L]
Yes it will indeed cause redirection loop since mod_rewrite rules are applied in a loop. Here value of REQUEST_URI changes to contact.php after first rule and to contact by your second rule.
To avoid this looping you need to use %{THE_REQUEST} in your external redirect rule as THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of some other rewrite rules. Example value of this variable is GET /index.php?id=123 HTTP/1.1.
Use this:
RewriteEngine On
# external redirect from /contact.php to /contact
RewriteCond %{THE_REQUEST} \s/+(contact)\.php\[\s?] [NC]
RewriteRule ^ /%1? [R=302,L]
# internal forward from /contact to /contact.php
RewriteRule ^(contact)/?$ $1.php [L,NC]
Change 302 to 301 once you make sure it is working fine for you.

CakePHP 301 Redirects appending extra query string parameter

I am trying to redirect old asp pages on a domain name so they link to their respective pages on the CakePHP version (using 1.3). The domain name is the same. These redirects are being added so results in search engines go to the new Cake page.
I have a bunch of Redirect 301's in my /.htaccess file (app/.htaccess and app/webroot/.htaccess are default).
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
Redirect 301 /contacts.asp http://domain/contacts
Redirect 301 /users.asp http://domain/users
</IfModule>
But for some reason, when I go to any of the urls to test the redirects, it appends an extra query string parameter. For example:
Going to: http://domain/contacts.asp results in http://domain/contacts?url=contacts.asp
So the redirect is working but it is appending the url query string parameter. I don't want to completely remove all query string parameters because some of the old asp links have query string parameters that I would also like passed to the corresponding Cake page.
I believe the "url" query string parameter is coming from the app/webroot/.htaccess file as seen:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
Note that when I put all my 301 redirects into my Virtual hosts file, the url parameter is not appended. I would like to keep all these redirects in my .htaccess file. How can I prevent this url query string parameter from being appended?
This looks like a case of mod_rewrite and mod_alias stepping over each other. The URI processing pipeline doesn't end when a Redirect directive is applied, it continues through the pipeline and mod_rewrite does its thing. Unfortunately, the end result isn't always what you want. You could just stick with mod_rewrite and drop the Redirect directives.
You can remove the 2 Redirect directives and add these 2 RewriteRules above the ones that map requests to the app/webroot:
RewriteRule ^contacts\.asp$ http://domain/contacts [L,R=301]
RewriteRule ^users\.asp$ http://domain/users [L,R=301]