I am trying to generate an external redirect that involves a few specific tasks.
If specific query string value is found in the URL, redirect.
If redirected, replace one of the query string parameter names but not its value.
If #1 is false, then ignore rewrite and proceed
Example: I have the url http://foobar.com/?a=123&b=456&c=blah
First, if parameter c = blah, redirect to http://barfoo.com/
Second, replace a with x parameter so the final URL is http://barfoo.com/?x=123&b=456&c=blah
Below is my best guess so far after researching on http://mod-rewrite-cheatsheet.com/ and Hidden features of mod_rewrite
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.foobar\.com$ [NC]
RewriteCond %{QUERY_STRING} ^a=(.*)&b=(.*)&c=blah$ [NC]
RewriteRule ^(.*)$ http://barfoo.com/?x=%1&b=%2&c=blah [NC,L,QSA,R=301]
However, the URL is appending the query string, not replacing.
I get redirected to http://barfoo.com/?x=123&b=456&c=blah&a=123&b=456&c=blah
smacks forehead
Removing QSA from the flags solved the issue. QSA means "append the existing query string to the current rewrite rule." It ignores whatever new query string parameters you are adding.
I thought it was needed to have query string parameters exist for the rewrite rule itself.
RewriteRule ^(.*)$ http://barfoo.com/?x=%1&b=%2&c=blah [NC,L,R=301]
Related
I want to redirect a URL in .htaccess, but want to keep the (dynamic) parameters from the query string at the end of the URL (e.g. ?id=1660, ?id=1661, etc.)
E.g.
https://mywebsite.example/service/viewinvoice.php?id=1660
I want to redirect it to:
https://mywebsite.example/whmcs-bridge/?ccce=viewinvoice.php?id=1660
So basically: https://mywebsite.example/service/viewinvoice.php?id=... needs to be redirected to https://mywebsite.example/whmcs-bridge/?ccce=viewinvoice.php?id=...
I tried this below, without any success
RewriteEngine On
RewriteCond %{QUERY_STRING} (^|&)/service/viewinvoice.php?id= [NC]
RewriteRule ^/?$ /whmcs-bridge/?ccce=viewinvoice.php [L,R=301]
I think this is not the right solution.
Does someone has suggestions?
You need to use the QSA (Query String Append) flag on your rewrite rule. From the documentation:
When the replacement URI contains a query string, the default behavior of RewriteRule is to discard the existing query string, and replace it with the newly generated one. Using the [QSA] flag causes the query strings to be combined.
From your example URLs, you don't need to match the query string in a rewrite condition. You are matching the URL path which is done as the first part of the rewrite rule itself.
Your rule should be:
RewriteEngine On
RewriteRule ^/?service/viewinvoice\.php$ /whmcs-bridge/?ccce=viewinvoice.php [L,R=301,QSA]
I am creating subdomain for all users in my website. I used wildcard subdomain and handling it with htaccess file with following code. This is working fine. It rewrites user1.mydomain.com to mydomain.com/subdir/index.php?user=user1
RewriteCond %{HTTP_HOST} !^www\.mydomain\.com
RewriteCond %{HTTP_HOST} ([^.]+)\.mydomain\.com [NC]
RewriteRule ^$ subdir/index.php?user=%1 [L]
Now, I need to add one more parameter to the url. Please suggest.
How to rewrite
user1.mydomain.com?data=value1 to mydomain.com/subdir/index.php?user=user1&data=value1
Specifying your own query string in the substitution URL, will by default discard any query string that existed on the original URL.
The QSA flag allows you to specify that you want your new query string, and the one from the originally requested URL, to be merged.
This is so elementary that you have to ask why it is so complex to implement.
Simply need to redirect one url to another on the same domain, the url contains query string aparams though:
I tried:
RewriteRule ^article.php?section=exclusive&id=543 articles/view/4639 [R=301,L]
I get page cannot be found - the redirect is not happening. I have other re-directs in the same htaccess which work. The query string params are causing problems, and escaping them also does not help.
Note the id's of the two urls are not the same and therefore I don't want a clever re-write rule which converts from one url to another with the query strings mapped to new params. I just want a fast and dirty mapping from A to B.
UPDATE
I tried this it redirects but it is adding my old query string to the end of the new url. How can I prevent that?
RewriteCond %{REQUEST_URI} ^/article\.php$
RewriteCond %{QUERY_STRING} ^section=exclusive
RewriteRule ^$ http://www.onlinegooner.com/articles/view/3000 [R=301,L]
Input url is: mydomain.com/article.php?section=exclusive
You may use this rule:
RewriteCond %{QUERY_STRING} ^section=exclusive [NC]
RewriteRule ^article\.php$ /articles/view/3000? [R=301,L,NC]
? in the target will strip off previous query string.
Since our product has switched from one coding framework to another, we need to modify some callback URLs from old third-parties for backward compatiblity. Basically the following two should work:
/oldLms/index.php?r=controller/action&code=randomCode
/lms/?r=site/newEndpoint&code=randomCode
The old oldLms directory is non existing now. That's why we need htaccess to forward requests from the first to the second.
The improtant points are the following:
The code query param should be passed to the new URL as a query param.
The r query param should not be passed since we have already hardcoded a new r as target that will handle the new logic. Passing the old r (controller/action in this case) will confuse the new framework into thinking that we are requesting something else.
Here's where we are at the moment:
RewriteCond %{QUERY_STRING} (^|&)r=controller/action(&|$) [NC]
RewriteCond %{QUERY_STRING} (^|&)code=(.*)(&|$) [NC]
RewriteRule ^oldLms/(.*) /lms/?r=site/newEndpoint&code=$4 [L,NC,QSA,R=302]
However, this doesn't seem to work since $4 does not return the value of the code query string parameter from the original URL.
Self answer:
RewriteCond %{QUERY_STRING} (^|&)r=controller/action(&|$) [NC]
RewriteCond %{QUERY_STRING} (^|&)code=(.*)(&|$) [NC]
RewriteRule ^oldLms/(.*) /lms/?r=site/newEndpoint&code=%2 [L,NC,R=302]
Removed [QSA] since it kept appending the full query string to the forwarded URL (including the r param).
Used %number instead of $number in the replacement URL to target selectors from the query string instead of from the original URL.
Also, in this case it had to be %2 instead of %4.
I have these rewrites. The first (for gallery) works as expected. The second (for photo) works but the query string is repeated. So it forwards to: http://www.domain.com/photo-TheID?id=TheID
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /gallery\.php\?set=([^/]*)\ HTTP/
RewriteRule ^gallery\.php$ http://www.domain.com/gallery?set=%1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /photo\.php\?id=([^/]*)\ HTTP/
RewriteRule ^photo\.php$ http://www.domain.com/photo-%1 [R=301,L]
However, if I add ? to the end of the rewriterule making it
RewriteRule ^photo\.php$ http://www.domain.com/photo-%1? [R=301,L]
It then works as expected forwarding to: http://www.domain.com/photo-TheID
My question is why is that query string being repeated without the "?" at the end? It's very confusing to me since the first rewrite (for gallery) does not have the ? yet it does not repeat the query string. If I add ? to the end of the gallery rewriterule it adds "%3f" to the end of the url.
Because it is appended automatically unless you place a trailing question mark in the substitution URL, provided it doesn't hold a new query string.
"When you want to erase an existing query string, end the substitution string with just a question mark".
Check the title Modifying the Query String in this Apache link.
Your question:
It's very confusing to me since the first rewrite (for gallery) does not have the ?
The reason is the first rewrite rule:
RewriteRule ^gallery\.php$ http://www.domain.com/gallery?set=%1
creates a new query string and in that case the incoming query string is not appended automatically unless you explicitly do it with the QSA flag.