I'm trying to redirect all of my products from my old zen-cart store to my new shopify store.
RewriteCond %{QUERY_STRING} products_id=1408
RewriteRule ^ https://shop.xyz.com/collections/products/mno? [L,R=301]
RewriteCond %{QUERY_STRING} ^products_id=1282 [NC]
RewriteRule ^ https://shop.xyz.com/collections/products/abc? [L,R=301]
RewriteCond %{QUERY_STRING} ^products_id=12 [NC]
RewriteRule ^ https://shop.xyz.com/collections/products/xyz? [L,R=301]
However, I can't figure out why products_id 12 and 1282 both redirect to https://shop.xyz.com/collections/products/xyz?
You line
RewriteCond %{QUERY_STRING} products_id=12 [NC]
contains the expression: products_id=12 which indeed matches both 12 and 1282.
If it's a single parameter, you can fix it by adding the end of string token $: products_id=12$
Otherwise there will be a delimiter & after the products_id number.
https://example.com/shop/?products_id=12&cat_id=1
you could match it with:
products_id=12&
Another unorthodox but quick and dirty solution that may work is to sort the numbers down, the higher numbers will match correctly before hitting the lower number rules.
Related
I'm aware this has already been asked, but I've tried countless solutions but I'm still not getting the desired result.
I've a page which shows a list of names and the variables data are the starting letter (variable l which can also be a number) and the page number (page_no) and the page number is optional as it should not be displayed in the page 1.
The original URL is the following
https://www.example.com/allnames.php?l=A&page_no=1
I've the following rule
RewriteCond %{QUERY_STRING} ^l=([\w]+)$
RewriteRule ^allnames.php$ /allnames/%1? [R=301,L]
which works fine for page 1, but it doesn't include the page_no variable, so I tried this one but I'm unable to understand what's wrong.
RewriteCond %{QUERY_STRING} ^l=([\w]+)?page_no=([0-9]+)$
RewriteRule ^allmovies.php$ /allmovies/%1/%2? [R=301,L]
the result expected would be, for example
allnames/A or allnames/A/1 for letter A, page 1
allnames/S/8 for letter S, page 8
And the following is the content of the htaccess file
RewriteEngine On
Options +FollowSymLinks -MultiViews
# to prevent loops
RewriteCond %{ENV:REDIRECT_STATUS} !200
#remove index.php
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by apache
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/index.php [L]
# allnames.php
RewriteCond %{QUERY_STRING} ^l=([\w]+)$
RewriteRule ^allnames.php$ /allnames/%1? [R=301,L]
RewriteRule allnames/ /allnames.php?l=$1&page_no=$2 [L]
RewriteCond %{QUERY_STRING} ^l=([\w]+)?page_no=([0-9]+)$
The regex in the condition (CondPattern) does not allow for the & delimiter between URL parameters. You are also allowing the l parameter value to be entirely omitted (which would result in an ambiguous URL) or contain multiple characters (which you've stated should be a single "letter").
You would seem to need something like the following instead:
RewriteCond %{QUERY_STRING} ^l=([\w])&page_no=([0-9]+)$
But note that this will fail if the l parameter value contains more than one character (or is omitted entirely).
the result expected would be, for example
allnames/A or allnames/A/1 for letter A, page 1
Note that you would still need your first rule (without the page_no URL param) to get allnames/A. You could instead make page_no optional in the second rule, but you would still get a trailing slash (ie. allnames/A/) if that is an issue?
I'm using Helicon Ape on a Windows Server to create htaccess files.
Originally, part of a larger set of conditions, I had this condition set to return 403 if the url contained (). However it is causing false positives in case of mailchimp tracking codes that end up getting wrapped in ()
RewriteCond %{QUERY_STRING} ^.*(\[|\]|\(|\)|<|>).* [NC,OR]
For example in the below URL
http://domain.com/page/11/page-name?ct=t(Newsletter_Tracking)
As an alternative, I was attempting to remove the parenthesis and redirect to a "cleaned version".
I tried a few different things that I found in SO but none worked.
So far the closest thing that I could get to working is this:
RewriteCond %{REQUEST_URI} [\(\)]+ [OR]
RewriteCond %{QUERY_STRING} [\(\)]+
RewriteRule ^(.*)[\(]+([^\)]*)[\)]+(.*)$ $1$2$3 [R=301,L]
The problem with the above code is that works if the () were in the URL but not the query string. It doesn't redirect and clean the querystring.
So this would work:
http://domain.com/page/11/pag(e-name)
but this wouldn't:
http://domain.com/page/11/page-name?ct=t(Newsletter_Tracking)
Your assistance is appreciated
Thank You.
You can use the following rule :
RewriteCond %{THE_REQUEST} /page/11/page-name\?ct=t\(Newsletter_Tracking\)\sHTTP [NC]
RewriteRule ^ %{REQUEST_URI}? [L,R]
If the querystring is dynamic, try:
RewriteCond %{THE_REQUEST} /page/11/page-name\?ct=.+\(.+\)\sHTTP [NC]
RewriteRule ^ %{REQUEST_URI}? [L,R]
Using #starkeen 's example, I was able to create a working solution.
This code handles the Query String separate from the URL. It cleans the URL but removes the query string.
RewriteCond %{REQUEST_URI} [\(\)]+
RewriteRule ^(.*)[\(]+([^\)]*)[\)]+(.*)$ $1$2$3 [R=301,L]
RewriteCond %{QUERY_STRING} [\(\)]+
RewriteRule ^ %{REQUEST_URI}? [R=301,L]
.htaccess and regular expressions is twisting my mind :)
I'm trying to catch a variable number of variables from the query string, write them in a cookie and redirect removing query string. I got it working with only one variable but sometimes I need it to catch 2 or 3. Here's the code that works with one variable:
RewriteCond %{QUERY_STRING} ^(tag|aid|flu)=([a-z0-9]+)$ [NC] # look for interesting variables in url
RewriteRule ^(.*)$ $1? [CO=%1:%2:foo.com:14400:/,R=301,L] # capture url strip for vars, write cookie, redir
but clearly this is not going to work if the requested url is foo.com?tag=xx&aid=yyy&flu=bbb or with just two variables. I just can't seem to wrap my head around how to do this. Also it would be nice if the order of the variables didn't matter.
Thanks!
I don't know if it's possible to do that:
# tag
RewriteCond %{QUERY_STRING} (?:^|&)tag=([a-z0-9]+)(?:&|$) [NC]
RewriteRule ^ - [CO=tag:%1:foo.com:14400:/]
# aid
RewriteCond %{QUERY_STRING} (?:^|&)aid=([a-z0-9]+)(?:&|$) [NC]
RewriteRule ^ - [CO=aid:%1:foo.com:14400:/]
# flu
RewriteCond %{QUERY_STRING} (?:^|&)flu=([a-z0-9]+)(?:&|$) [NC]
RewriteRule ^ - [CO=flu:%1:foo.com:14400:/]
# Final
RewriteCond %{QUERY_STRING} (?:tag|aid|flu)=.+ [NC]
RewriteRule ^(.*)$ $1? [R=301,L]
How can i replace + to - in my url. What code shoud I add in my htacces to get rid of + and replace it with a minus.
RewriteCond %{QUERY_STRING} ^search=([^&]+)$
RewriteRule ^ http://mysite.com\/Download\/free\/%2.html? [R,L,NE]
If i type a search that contain spaces, every space become + and i want -.
I'm assuming that the bla+bla+bla part of the URL: http://mysite.com/Download/free/bla+bla+bla.html originated from the query string search='s value. Depending on what other rules you may have, you can go about this in 2 different ways. You can either remove all of the spaces from the query string first, before it's redirected to the .html file. Or you can rewrite the query string into the URI, then remove the spaces before redirecting. It'll be something like this:
RewriteCond %{QUERY_STRING} ^search=(.*?)(\+|%20)(.*)$
RewriteRule ^ /?search=%1-%3 [L,NE]
RewriteCond %{QUERY_STRING} !(\+|%20)
RewriteCond %{QUERY_STRING} ^search=([^&]+)$
RewriteRule ^ http://mysite.com\/Download\/free\/%1.html? [R,L,NE]
Note that in your htaccess you have the %2 back reference, which doesn't seem to reference anything.
Or rewrite to URI first, then redirect:
RewriteCond %{QUERY_STRING} ^search=([^&]+)$
RewriteRule ^ /Download\/free\/%1.html? [L,NE]
RewriteCond %{REQUEST_URI} !(\ )
RewriteRule ^ - [L,R]
RewriteRule ^(.*)\ (.*)$ /$1-$2 [L]
I'm trying to add one last improvement (regarding htaccess), and that is that I would like it to redirect /?mod=inicio to /inicio. So I'm trying to do it with the following code, but It keeps building the url like this /inicio?mod=inicio
RewriteCond %{QUERY_STRING} ^mod=([a-z]+)$ [NC]
RewriteRule .* /%1 [L]
Same thing with extra parameters: from /?mod=x&type=y-z to /x/y-z
Try these rules instead:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /\?mod=([a-z]+)&type=([a-z\-]+)
RewriteRule ^ /%1/%2? [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /\?mod=([a-z]+)($|\ )
RewriteRule ^ /%1? [L]
The key is to match against the actual request instead of the URI because your other rules (from your previous question) will cause these rewrites to match, they'll conflict with each other. The other key point is to include a ? at the end of the targets (e.g. /%1/%2?) which makes it so the query string doesn't get appended.