.htaccess redirect if contains string keeping some parameters - apache

I'm trying to redirect a route to a subdomain if it contains a certain string:
For example, if domain contains /foo/bar/:
http://example.com/foo/bar/123/456.jpg should be redirected to the subdomain http://sub.example.com/bar/123/456.jpg.
I mean, I would need to remove only /foo/ from the route and redirect the result to a subdomain.
I don't know how to remove a certain string in the middle of the route keeping following strings.

Try something like the following near the top of the .htaccess file in the root of example.com:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^foo/(bar/\d+/\d+\.jpg)$ http://sub.example.com/$1 [R,L]
If the subdomain points to a completely different area of the filesystem then you can remove the RewriteCond directive that checks the hostname. Or if the /foo/ prefix should always be removed (regardless of which host is requested).
This matches requests of the form /foo/bar/<number>/<number>.jpg.
$1 is a backreference to the captured group in the RewriteRule pattern that specifically omits the foo/ prefix.
This is a temporary (302) redirect.
if domain contains /foo/bar/
That is part of the URL-path, not the domain.

Related

.htaccess redirect not redirecting

I am trying to Redirect pages to new location on the same website using .htaccess
the physical file name is displayitems.php but there is a rule in .htaccess
RewriteRule ^buy-online-(.*) ./displayitems.php?url=$1
which is to handle the user friends URLs and works well.
Now i want to redirects these user friendly urls to new location which is on the same website for eg.
redirect https://example.com/buy-online-alhabib-rings4-sku-1658906163 https://example.com/products/jewelry/buy-online-alhabib-rings4-sku-1658906163 [R=301]
redirect https://example.com/buy-online-alhabib-rings3-sku-1658906162 https://example.com/products/jewelry/buy-online-alhabib-rings3-sku-1658906162 [R=301]
redirect https://example.com/buy-online-alhabib-rings2-sku-1658906161 https://example.com/products/jewelry/buy-online-alhabib-rings2-sku-1658906161 [R=301]
redirect https://example.com/buy-online-alhabib-rings1-sku-1658906160 https://example.com/products/jewelry/buy-online-alhabib-rings1-sku-1658906160 [R=301]
these user friendly url doesn't have any extensions like ".php" ".htm" etc
but nothing happening.
I have added this code in php file to check if url doesn't contain \products\ than redirect it to new location with the same name, for testing i just redirect it with 302 once all tested i will change it to 301
if (strpos($_SERVER['REQUEST_URI'], "/products/") === false) { $NewAddress = strtolower("Location:". $ini['website_address_https'] . "products/".$Product['categoriesname']."/".$Product['BrandName'].$_SERVER['REQUEST_URI']); header("$NewAddress",TRUE,302); }
redirect https://example.com/buy-online-alhabib-rings4-sku-1658906163 https://example.com/products/jewelry/buy-online-alhabib-rings4-sku-1658906163 [R=301]
There are 3 main issues here:
The mod_alias Redirect directive takes a root-relative URL-path (starting with a slash) as the source URL, not an absolute URL. So the above will never match.
You have mixed syntax with mod_rewrite. [R=301] is a RewriteRule (mod_rewrite) flags argument and has nothing to do with the mod_alias Redirect directive. Redirect takes the HTTP status code as an optional second argument. eg. Redirect 301 /buy-online-alhabib-rings4-sku-1658906163 ...
Since you are using mod_rewrite (ie. RewriteRule) for your internal rewrite, you should use mod_rewrite for external redirects as well to avoid potential conflicts. These redirects then need to go before your internal rewrite.
Additionally,
In the 4 redirects you have posted it looks like you are simply injecting /products/jewelry at the start of the URL-path. This does not need 4 separate rules, providing you are wanting to redirect all URLs that following this particular format.
Try the following instead:
RewriteEngine On
# Inject (redirect) "/product/jewelry" at the start of the URL-path
RewriteRule ^buy-online-alhabib-rings\d-sku-\d+$ /products/jewelry/$0 [R=301,L]
# Internal rewrite
RewriteRule ^buy-online-(.*) displayitems.php?url=$1 [L]
The $0 backreference in the first rule contains the entire URL-path that is matched by the RewriteRule pattern.
Note that I also removed ./ from the start of the substitution string in the last rule. This is unnecessary here.

.htaccess 301 redirect whole URL including Domain

I need to redirect around 300 URLs on a multidomain site that has the same URL structure on the different domains. For example:
https://www.example.com/de/products.html needs to be redirected to https://www.example.org/de/products.html
So my usual approach does not work:
RedirectMatch 301 /de/products.html$ /de/products.html
I would need something like
RedirectMatch 301 https://www.example.com/de/products.html$ https://www.example.org/de/products.html
which obviously doesn't work or I just didn't get to work.
Not sure if important, but it's a TYPO3 instance.
The mod_alias RedirectMatch directive matches against the URL-path only. To match the hostname you'll need to use mod_rewrite with an additional condition (RewriteCond directive) that checks against the HTTP_HOST server variable (the value of the Host HTTP request header).
Also, since the URL structure is the same on both domains then you only need a single rule - just use the same URL-path from the initial request. No need to do one-by-one redirects as you seem to be trying to do.
For example, the following would need to go at the top of the .htaccess file before any existing rewrites:
RewriteEngine On
# Redirect everything from example.com to example.org and preserve the URL-path
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule ^ https://www.example.org%{REQUEST_URI} [R=301,L]
This checks for both example.com and www.example.com.
The REQUEST_URI server variable already contains a slash prefix, hence it is omitted in the substitution string.
Test first with a 302 (temporary) redirect to avoid potential caching issues.
UPDATE:
But I don't want to redirect all URLs, just some.
To redirect a specific URL to the same URL at the target domain, as per your original example:
# Redirect "/de/product.html" only
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule ^de/products\.html$ https://www.example.org/$0 [R=301,L]
The above redirects https://www.example.com/de/products.html only to https://www.example.org/de/products.html.
The $0 backreference contains the entire URL-path that the RewriteRule pattern matches against.
How to extend your snippet with /de/ or /fr/ etc.? For example I want to redirect example.com/de/products.html but not example.com/products.html
Maybe the above example is what you require. Alternatively, to redirect /de/<something> (or /fr/<something>) only and not just /<something>, you could do something like this:
# Redirect "/<lang>/<something>" only, where <lang> is "de" or "fr"
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule ^(de|fr)/[^/]+$ https://www.example.org/$0 [R=301,L]
The above will redirect https://example.com/de/<something> to https://www.example.org/de/<something>.

Redirect >> domain.com/test to another url (domain.com/test3 using .htaccess (wp)

I am trying to redirect one complete URL
But this is not working ...
RewriteCond %{HTTP_HOST} ^https://www.moccioso.com/d.php?
id=ultimateselection.zip$
RewriteRule ^$ http://moccioso.com/sd_product/ultimateselection-zip
[L,R=301]
(I'm assuming you've not wrapped the code onto multiple lines in your actual code?)
The HTTP_HOST variable contains the Host HTTP request header. ie. the hostname specified on the request eg. www.example.com only - there is no scheme, URL-path or query string here. So, this RewriteCond directive will never match.
But you are also trying to match an empty URL-path with the RewriteRule pattern ^$ - so again, this will never match. In your example the URL-path is /d.php. The RewriteRule pattern matches against the URL-path only.
You are also redirecting to http (not https) in this directive? Your example uses https. You are also removing the www subdomain, but again, your example includes it?
If you are redirecting from/to the same hostname and only have one domain then you don't need to explicitly include the domain name (ie. the requested hostname) in the rule.
To match against the query string you need to match against the QUERY_STRING server variable.
Try the following instead, near the top of your .htaccess file.
RewriteCond %{QUERY_STRING} ^id=ultimateselection\.zip$
RewriteRule ^d\.php$ /sd_product/ultimateselection-zip [R=301,L]
This will need to go near the top of your .htaccess file. Test first with a 302 (temporary) redirect to avoid potential caching issues.
Clear your browser cache before testing.

htaccess url parameter rewrite for specific page as subdomain

I want to change my specific page URL as subdomain by .htaccess from
example.com/page.php to page.example.com.
We need to make some assumptions, since you've not included this information in the question:
You are requesting (ie. linking to) page.example.com and you wish to serve /page.php.
Both the subdomain page.example.com and domain apex example.com point to the same area of the filesystem, so both hostnames serve the same content.
In which case it is a relatively straight forward internal rewrite from page.example.com to page.example.com/page.php (based on assumption #2 above).
In your .htaccess file, you can achieve this using mod_rewrite:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(page)\.example\.com
RewriteRule ^$ %1.php [L]
The %1 backreference simply holds the value page from the preceding CondPattern.
This only matches requests for https://page.example.com/ and not https://page.example.com/<something>

Mod Rewrite -- redirect all content from subdirectory

I have a scenario where there is a a site with subdirectories and content etc originally in a subdirectory /main
The site and all content has been moved back to the root and is working fine
We need to rewrite so that any http call to /main/, /main/page1, /main/page2 etc is redirected back to the / directory but the uri /page1, /page2 etc
This is what we have so far
RewriteCond %{REQUEST_URI} ^/main/.*
RewriteRule ^/main/(.*) /$1 [L]
Any comments welcome
Thanks very much
In .htaccess context, the url that is matched in the first parameter of RewriteRule doesn't include a leading slash and doesn't include the query string. Having a leading slash will cause the rule to never match. In your case your RewriteCond is unnecessary, as it matches exactly what the RewriteRule would match. Change your rule to the following url and it should work. Please note that this is an internal rewrite (the client won't see this change). If you need a redirect (the client will display the url without main in the address bar), add the [R] flag to the rule.
RewriteRule ^main/(.*)$ $1 [L]
See the documentation.