Can't pass parameters to another redirect website - apache

I want to redirect to another website, and pass the parameters also.
Example: I go to my website: source.example/?code=12345
Then, I want it to redirect to target.example/?code=12345.
I am currently using this for my .htaccess file, since I figured out from other posts that if I query a certain parameter, it will get passed also:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^code=[NS]$
RewriteRule "www.google.com" /$1 [R=302,L]
Also, I tried many different approaches looking at these stack questions:
simple .htaccess redirect : how to redirect with parameters?
Redirect and keep the parameter in the url on .htaccess
But I can't get it running :(

since I figured out from other posts that if I query a certain parameter, it will get passed also
This is not true. The query string is passed through by default - there is nothing extra you need to do if you want the same query string on the target URL.
RewriteCond %{QUERY_STRING} ^code=[NS]$
RewriteRule "www.google.com" /$1 [R=302,L]
This code won't match the source URL for many reasons:
"www.google.com" - The first argument to the RewriteRule directive is a regex that matches the source URL-path (less the slash prefix). In your example the URL-path is empty.
^code=[NS]$ matches either code=N or code=S - which is not the intention from your example. (The [NS] looks like a mangled RewriteRule flag?!)
/$1 - this is the substitition string, ie. the URL you want to redirect to. (The $1 backreference is always empty, so this is meaningless.)
To redirect from source.example/?code=<number> to https://target.example/?code=<number> then try the following instead:
RewriteCond %{HTTP_HOST} ^source\.example [NC]
RewriteCond %{QUERY_STRING} ^code=\d+$
RewriteRule ^$ https://target.example/ [R=302,L]
This only matches a query string of the form code=1234. It does not match code= or code=1234&foo=bar, etc.
The query string is passed through by default.
If source.example is the only domain being hosted at the current location then you can remove the first condition that explicitly checks the requested hostname.
The order of directives in the .htaccess file is important. An external redirect like this should go near the top.

Related

apache query string rewrite rules

I am setting up Query string redirect :
expo.com/en/general/campaigns/on-second-thought.html?slide=ost-2016-tank to
expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html
RewriteCond %{HTTP_HOST} ^(.*)expo\.com
RewriteCond %{QUERY_STRING} slide=ost-2016-tank
RewriteRule  ^/en/general/campaigns/on-second-thought.html?$  http://www.expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html [R=301,L,NC]
redirect happening but its appending ?slide=ost-2016-tank like below
http://www.expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html?slide=ost-2016-tank
slide=ost-2016-tank parameter is added to redirected page
Since your rule does not define a new query string, the default behavior of Apache is to copy the old query string to the new URL. To get rid of it, append a ? to the address you rewrite/redirect to:
RewriteRule ^/en/general/campaigns/on-second-thought\.html?$ http://www.expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html? [R=301,L,NC]
Or, for Apache >= 2.4, you can also use the flag QSD (Query String Discard):
RewriteRule ^/en/general/campaigns/on-second-thought\.html?$ http://www.expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html [R=301,L,NC,QSD]
Simply add a blank query string when redirecting:
RewriteCond %{HTTP_HOST} ^(.*)expo\.com
RewriteCond %{QUERY_STRING} ^slide=(ost-2016-tank)$
RewriteRule ^(/?en/general/campaigns/on-second-thought)\.(html)$ $1/%1.$2? [R=301,L,NC]
No need to mention http://expo.com again when redirecting. It'll automatically redirect to the same hostname because of R flag. No need to repeat same strings over and over. Using match groups and referencing them later works.
Your pattern had .html?$ in it, which actually means that it'll match .html as well as .htm. You do not receive query strings in RewriteRule context.

Redirect www to non-www loses Google gclid tracking code

I've used the .htaccess code in Generic htaccess redirect www to non-www to successfully redirect www.mysite.com to mysite.com, however in the process it strips off the gclid parameter and now AdWords isn't counting clicks correctly.
Is it possible to amend the code below so that any parameters are retained after the redirect?
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
From: https://wiki.apache.org/httpd/RewriteFlags/QSA
QSA = Query String Append.
This rule appends the GET query string which results from the ReWrite rule to the initial GET query string sent by the browser. For example, take the following RewriteRule:
RewriteRule ^/product/([0-9]*)/? /product.php?product_id=$1 [QSA]
This simply makes the product_id number look like a directory to the user. Now say that I have two different views of the page, view=short and view=long. For whatever reason, I don't want to make these views look like directories by using a RewriteRule. So I want to be able to do things like:
http://example.com/product/1351283/?view=short
Let's see how QSA works. With QSA, my final rewritten URL is
http://example.com/product.php?product_id=1351283&view=short
QSA has caused the RewriteEngine to append the existing query string (view=short) to the new query string (product_id=1351283). Without QSA, the existing query string is simply replaced by the new query string:
http://example.com/product.php?product_id=1351283
If you do much scripting with reliance on GET variables, it is virtually imperative that you enable the QSA flag on all of your RewriteRules.

How to mod_rewrite redirect php-file-url to new path

I want to redirect
http://api.domain.com/api.php?debug=true
to
http://api.domain.com/getData/?debug=true
What's wrong?
RewriteCond %{REQUEST_URI} !^/api\.php/.*
RewriteRule ^(.*)$ /getData/$1
Also not working
RewriteRule ^/api\.php(.*)$ /getData/$1 [PT]
That did the job
RewriteRule ^api.php$ /getData/
Let me first tell you what is wrong with your two attempts:
RewriteCond %{REQUEST_URI} !^/api\.php/.*
RewriteRule ^(.*)$ /getData/$1
This translates to: If the URI part of the url (after the domain and before the query string) does not match api.php, translate ^(.*)$ to /getData/$1. You want however to do it when the uri does match that string, making the condition obsolete.
RewriteRule ^/api\.php(.*)$ /getData/$1 [PT]
You tried to match the query string here with (.*), but that is not how it works. Besides that, in per-directory context (which is what .htaccess is), the url never starts with a slash. ^/ therefore never ever matches.
If you don't define a query string in the rewritten part, then the query string of the old url is appended to the new url. The correct rewriterule would be:
RewriteRule ^api\.php$ getData [R=301,L]
Please note that \. means "a literal dot". If I wouldn't escape it, then apisphp would redirect too. The R=301 flag will make it an external permanent redirect. The L flag will say that this is the last rule to match for this run through .htaccess. This is to prevent other rules matching on the full url, causing all kind of weird behaviour.

What's going on with my mod_rewrite?

I have a simple mod_rewrite system set up on my site which basically converts
http://site.com/file -> http://site.com/file.php
Here's the .htaccess file
Options -MultiViews
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.site.com
RewriteRule ^(.*)$ http://site.com/$1 [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)/?$ http://site.com/$1.php [L]
This was working for a long time and then a couple of days ago I realized that while the RewriteRule was working, it was actually changing my URL in the status bar.
For instance, it would redirect /photos to /photos.php, but it would also change the URL to show the .php. This has never happened before and I'm not sure what happened to trigger the change.
Any ideas?
The first rewrite rule needs the [L] flag. From the mod_rewrite documentation for the [R] flag:
You will almost always want to use [R] in conjunction with [L] (that is, use [R,L]) because on its own, the [R] flag prepends http://thishost[:thisport] to the URI, but then passes this on to the next rule in the ruleset, which can often result in 'Invalid URI in request' warnings.
In this case, you don't get a warning, but appending the ".php" extension happens before issuing the redirect rather than when the second, redirected request comes in.
Also, remove the scheme and domain name from the substitution in the second rewrite rule. A full URL can cause an implicit redirect. From the documentation for RewriteRule:
The Substitution of a
rewrite rule is the string that replaces the original URL-path that
was matched by Pattern. The Substitution may
be a:
[...]
Absolute URL
If an absolute URL is specified,
mod_rewrite checks to see whether the
hostname matches the current host. If it does, the scheme and
hostname are stripped out and the resulting path is treated as
a URL-path. Otherwise, an external redirect is performed for
the given URL. To force an external redirect back to the
current host, see the [R] flag below.

What RewriteRule would be to redirect based on the on query string parameters?

If requested page page1.html and in query string uin is anything but not 12 or 13, let them see this page1.html page, otherwise redirect them to page2.html
Update: BTW, there are also other params in the query string. They should be sent to either page too.
The Rewrite Condition you're looking for is %{QUERY_STRING}
Here's another SO question doing something similar: Redirecting URLs (with specific GET parameters)
This will redirect to page2.html if uin=12 or uin=13. The entire query string will be sent to the page2.html page:
# EDIT: Doesn't properly handle all cases
RewriteCond %{QUERY_STRING} [\&]+uin=1[23][&]+ [OR]
RewriteCond %{QUERY_STRING} ^uin=1[23][&]+
RewriteRule ^/page1\.html /page2.html [R]
EDIT: This is a lot better and will handle the parameter in any position in the query string, beginning or end, and will also account for filtering out cases where the string is within another parameter, like suin=123
RewriteCond %{QUERY_STRING} ^(.*&)*uin=1[23](&.*)*$
RewriteRule ^/page1\.html /page2.html [R]
I tested on the following cases:
Redirected:
http://local.sandbox.com/page1.html?hello=world&uin=13&test=1
http://local.sandbox.com/page1.html?uin=12&test=1
http://local.sandbox.com/page1.html?uin=12
http://local.sandbox.com/page1.html?uin=13
http://local.sandbox.com/page1.html?uin=13&t=t
http://local.sandbox.com/page1.html?t=t&r=r&uin=13&t=3
http://local.sandbox.com/page1.html?t=t&uin=13
Didn't redirect:
http://local.sandbox.com/page1.html?uin=11&test=1
http://local.sandbox.com/page1.html?hello=world&uin=1&test=1
http://local.sandbox.com/page1.html?hello=world&ui=13&test=1
http://local.sandbox.com/page1.html?t=t&&r=r&suin=13&t=3
http://local.sandbox.com/page1.html?t=t&&r=r&uin=134&t=3
http://local.sandbox.com/page1.html?suin=134&t=3
http://local.sandbox.com/page1.html?auin=13&t=t
http://local.sandbox.com/page1.html?uin=134&t=3
http://local.sandbox.com/page1.html?t=t&uin=134
http://local.sandbox.com/page1.html?t=t&auin=13