Rewrite URL containing directory path and parameters to parameter based URL using both path and query string - apache

I use htaccess to rewrite this path:
/inventory/products/tools/
to this url with query string:
/inventory.php?cat=products&type=tools
using the following rule:
RewriteRule ^inventory/(.*)/(.*)/? /inventory.php?cat=$1&type=$2 [L,R=301]
When I add a query string to my url path
/inventory/products/tools/?sort=pricehigh
and use this rule
RewriteCond %{QUERY_STRING} ^(.*)$ [NC]
RewriteRule ^inventory/(.*)/(.*)/? /inventory.php?cat=$1&type=$2&%1 [L,R=301]
I am getting a redirect loop and the urlstring is rewritten over and over
I am trying to end up with the following destination url
/inventory.php?cat=products&type=tools&sort=pricehigh
In the example rule above I am using R=301 in order to visualize the url.
In a production I would use [L] only

Without the trailing slash, the second (.*) also allows for matching zero characters - so due to the greediness of regular expressions, the first (.*) matches products/tools already.
The following should work:
RewriteRule ^inventory/([^/]+)/([^/]+)/?$ /inventory.php?cat=$1&type=$2 [QSA,L,R=302,NE]
([^/]+) demands one or more characters, out of the class of characters that contains everything but the /.
The NE/noescape flag seems necessary here for some reason, otherwise the resulting query string will contain ?cat=products%26type=..., with the & URL-encoded.

Related

I want to remove a string with a question mark at the end of my URL with .htaccess

I want to remove the string
?mobile=1
out from different URLs with .htaccess. So:
https://www.example.com/?mobile=1 should become https://www.example.com/
and
https://www.example.com/something/?mobile=1 should become https://www.example.com/something/
I tried the following
RewriteEngine On
RewriteRule ^(.+)?mobile=1 /$1 [R=301,L,NC]
But that does not seem to work. Any ideas?
RewriteRule ^(.+)?mobile=1 /$1 [R=301,L,NC]
The RewriteRule pattern matches against the URL-path only, which notably excludes the query string. So the above would never match. (Unless there was a %-encoded ? in the URL-path, eg. %3F)
To match the query string you need an additional condition (RewriteCond directive) and match against the QUERY_STRING server variable.
The regex .+ (1 or more) will not match the document root (ie. your first example: https://www.example.com/?mobile=1). You need to allow for an empty URL-path in this case. eg. .* (0 or more).
For example, try the following near the top of your root .htaccess file:
RewriteCond %{QUERY_STRING} =mobile=1
RewriteRule (.*) /$1 [QSD,R=301,L]
This matches the query string mobile=1 exactly, case-sensitive (as in your examples). No other URL parameters can exist. The = prefix on the CondPattern makes this an exact match string comparison, rather than a regex as it normally would.
And redirects to the same URL-path, represented by the $1 backreference in the substitution string that contains the URL-path from the captured group in the RewriteRule pattern.
The QSD (Query String Discard) flag removes the query string from the redirect response.
Test first with a 302 (temporary) redirect and and only change to a 301 (permanent) - if that is the intention - once you have confirmed this works as intended. 301s are cached persistently by the browser so can make testing problematic.

Can't pass parameters to another redirect website

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.

RewriteRule expression not working

I want to rewrite a URl to another, but the Rewrite expression is not working.
Ex. URL1: "http://www.demo.com/de-ch/case1/?id=23"
And
Ex. URL2: 'http://www.demo.com/de-ch?id=23'
RULE: RewriteRule ^(.....)([\?]|(.*))$ http://www.result.com/$1
This rule gives follow result:
http://www.result.com/de-ch?id=23
But I just need the iso codes http://www.result.com/de-ch
What am I missing in the Regex?
You can't match against the query string in the rule's pattern. The query string isn't technically part of the path. You'll need to use a RewriteCond and the %{QUERY_STRING} variable:
RewriteCond %{QUERY_STRING} ^id=23
RewriteRule ^(.....) http://www.result.com/$1?
Note the "?" at the end of the rule's result. That will remove the query string.
However, since you're not doing anything with the query string, you can just leave it out entirely and only have:
RewriteRule ^(.....) http://www.result.com/$1?
Note that this rule will cause the browser to get redirected to http://www.result.com/de-ch and if you don't have a resource that resolves at that URL, then you'll simply get a 404 or some related error.

Remove query string from url using rewrite rule

Im trying to rewrite url in htaccess file.
Original url:
www.mywebsite.com/flash/module.swf?xmlpath=http%3a%2f%2f0.0.0.0%3a8000%2fconfig.xml
I want to remove query string from this url. This condition should applied only for .xml extension.
Output URL should be
www.mywebsite.com/flash/module.swf
You can match a query string with a RewriteCond and %{QUERY_STRING}. If the second argument of a RewriteRule contains a query string, it will overwrite the existing query string. Clearing the query string is as easy as appending a ? to your url ;-) Alternativelly, you can use the QSD (Query String Discard) flag.
RewriteCond %{QUERY_STRING} \.xml$
RewriteRule ^flash/module\.swf$ flash/module.swf? [L]
Change the flags ([L]) to [R,L] or [R=301,L] if you want this to be an external redirect instead.

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.