I have multiple sites (subdirectories). I want to redirect all URLs of the format /(*)/login to /other/login.
I have tried:
RewriteRule ^/(.*)/login /other/login
#and
^(.*)/login /other/login
I've also tried Redirect.
Additionally, I notice that some subfolders have their own .htaccess files also. Do I need to put the redirect rule in the subfolder's .htaccess file? There surely must be a more efficient way.
I notice some subfolder have their own .htaccess files also, do I need to put the redirect rule in the subfolder .htaccess files?
Any mod_rewrite directives in child .htaccess files will, by default, completely override the mod_rewrite directives in any parent .htaccess file, they are not inherited. However, you can change this behaviour. On Apache 2.2 this is quite limited as you would need to change the child .htaccess file anyway, so it would probably be easier to simply duplicate this directive in the child config. But on Apache 2.4.8+ you can do all this in the parent .htaccess file. For example:
RewriteEngine On
RewriteOptions InheritDownBefore
RewriteCond %{REQUEST_URI} !^/other
RewriteRule ^[^/]+/login$ /other/login [R=302,L]
The InheritDownBefore option results in the current mod_rewrite directives being applied before the mod_rewrite directives in any child configs.
The RewriteCond directive is required in order to prevent a redirect loop (if the /other subdirectory does not have its own .htaccess file containing mod_rewrite directives).
This is an external "redirect" (as stated in your question). The URL changes in the browser's address bar. You can possibly change this to an internal rewrite (as your current directive implies) by removing the R flag (although this may depend on your application).
If you simply want a "redirect" then you could probably use a mod_alias RedirectMatch directive instead of the above mod_rewrite directives. This runs separately to mod_rewrite, but note that any mod_rewrite directives (in child configs) are processed first. For example:
RedirectMatch 302 ^/(?!other)[^/]+/login$ /other/login
The RedirectMatch directive uses a regex, whereas Redirect (also mod_alias) uses simple prefix matching. So, you couldn't match this specific pattern using a simply Redirect.
The (?!other) part is a negative lookahead (zero-width assertion) that checks that the URL-path being matched does not start other - in order to avoid a redirect loop.
Note also that RewriteRule does not use the slash prefix on the URL-path, whereas, RedirectMatch does. And there is no need to capture the URL-path (ie. by enclosing the regex in parentheses) if this is not required.
I have try several variants (you can see marked lines, that doesn't works),
my .htaccess:
#AddType application/x-httpd-php .html .htm
RewriteEngine on
RewriteRule ^(.*)$ index.php?path=$1 [NC,L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule ^([^/]*)+^(.*)$ index.php?dir=$1&path=$2 [NC,L,QSA]
#RewriteRule ^(.*)$ index.php?path=$1 [NC,L,QSA]
#FallbackResource index.php
It works with all urls: /, /index, /index.html, /main/main.html.
Then echo var_dumps($_GET); gives:
array(1) { ["path"]=> string(10) "index.html" }
Now all requests goes into index.php.
Related
I tried many commands like the following
RewriteRule ^(.*?)/(.*?)/(.*?)$ $1.php?$2=$3 [L]
in .htaccess to hide the php extension from the URL but do not work, I have the following site.org/home.php and I want it to site.org/home, how can I do this? Is it possible to do it without modifying .htaccess file as well?
I tried this as well in the .htaccess file and doesn't work
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)$ $1.php
</IfModule>
You don't actually "hide" the extension using .htaccess (if that is what you are expecting). You must first remove the .php extension in your HTML source, in your internal links (Apache/.htaccess should not be used to do this). The extension is now "hidden" (but the links don't work).
You then use .htaccess to internally rewrite the extensionless URL back to the .php extension in order to make the URL "work".
For example:
RewriteEngine On
# Rewrite to append ".php" extension if the file exists
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.+) $1.php [L]
Given a request for /home, the above will internally rewrite the request to /home.php if home.php exists as a physical file in the document root.
Note that this rule does assume your URLs do not end in a slash. eg. It expects /home and not /home/. if you request /home/ then it will result in a 404, since /home/.php does not exist.
The preceding condition first checks that the requested URL + .php exists as a physical file before rewriting the request. This is necessary in order to prevent a rewrite loop (500 error).
If your URLs do not contain dots (that are otherwise used to delimit the file extension) then the above can be optimised by excluding dots in the matched URL-path. ie. Change the RewriteRule pattern from (.+) to ^([^.]+)$. This avoids your static resources (.css, .js, .jpg, etc.) being unnecessarily checked for the corresponding .php file.
If you are changing an existing URL structure that previously used the .php extension and these URLs have been indexed by search engines and/or linked to by third parties then you should also redirect requests that include .php in order to preserve SEO. This redirect should go before the above rewrite, immediately after the RewriteEngine directive:
# Redirect to remove ".php" extension
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)\.php$ /$1 [R=301,L]
The preceding condition that checks against the REDIRCT_STATUS environment variable ensures that only direct requests are stripped of the .php extension and not rewritten requests by the later rewrite (which would otherwise result in a redirect loop).
NB: Test with a 302 (temporary) redirect first to avoid potential caching issues.
RewriteRule ^(.*?)/(.*?)/(.*?)$ $1.php?$2=$3 [L]
This does considerably more than simply "removing" (or rather "appending") the .php extension.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)$ $1.php
</IfModule>
This will result in a rewrite-loop, ie. a 500 Internal Server Error response as it will repeatedly append the .php extension again and again to the same request.
(The <IfModule> wrapper is not required.)
I want to redirect via .htaccess
https://www.example.co/en/brand/Abc to https://www.example.co/en/brand/abc
I have tried
RewriteRule ^https://www.example.co/en/brand/Abc https://www.example.co/en/brand/abc [R=301,L]
The RewriteRule pattern (1st argument to the RewriteRule directive) matches against the path-part of the URL only, ie. /en/brand/Abc. An additional complication in per-directory .htaccess files is that the URL-path that is matched is also less the directory prefix (which always starts with a slash), so the URL-path does not start with a slash. In other words: en/brand/Abc (for an .htaccess file in the document root).
So, you will need to format the directive like this instead:
RewriteRule ^en/brand/Abc$ https://www.example.co/en/brand/abc [R=301,L]
(Assuming you already have RewriteEngine On defined and that this is near the top of your .htaccess file.)
Reference:
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
You may try something like this:
Options +FollowSymlinks -MultiViews
RewriteEngine On
# Don't want loops
RewriteCond %{REQUEST_URI} !/abc
RewriteCond %{REQUEST_URI} /Abc
RewriteRule . https://www.example.co/en/brand/abc [R=301,L]
URL are usually case-sensitive. Check this document, while domain names are not. Therefore "abc" and "Abc" are not the same and that's what the question is about. I think.
I am trying to redirect these pages
/reviews/page/2/
/reviews/page/3/
to this
/reviews/
using this line:
Redirect 301 /reviews/page/./ /reviews/
But it's not working. I've tried other combinations like .* and ^.*$ but nothing works. Only a specific URL will get redirected to the new one.
Is there anything else that could interfere with the line I'm trying to work? Maybe space, uppercase, lower case, indent, etc?
The whole file is pasted below.
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# --------------------------------
# | ADDITIONAL RULES |
# --------------------------------
<FilesMatch "^robots\.txt">
Order Allow,Deny
Allow from all
</FilesMatch>
<FilesMatch "^\.htaccess|.*\.cgi">
Order Deny,Allow
Deny from all
</FilesMatch>
Redirect 301 /reviews/page/./ /reviews/
The mod_alias Redirect directive is prefix-matching, it does not accept wildcards or regex. So, you could theoretically do something like:
Redirect 301 /reviews/page/ /reviews/
However, as mentioned, the Redirect directive is prefix-matching and everything after the match is copied onto the end of the target URL. So, a request for /reviews/page/2/ would be redirected to /reviews/2/ - which is not desirable.
You could use RedirectMatch instead, which uses regex rather than simple prefix matching. However, since you are already using mod_rewrite (RewriteRule) directives, it is preferable to use mod_rewrite for this in order to avoid potential conflicts. Different Apache modules execute at different times during the request, regardless of the apparent order of these directives in the config file.
Instead, try the following mod_rewrite directive at the top of your .htaccess file, immediately after the RewriteEngine directive:
RewriteRule ^reviews/page/[23]/$ /reviews/ [R=302,L]
This matches any request for /reviews/page/2/ or /reviews/page/3/ and redirects to /reviews/. The 2 or 3 are matched using a character class. Note that in per-directory .htaccess files the URL-path that the RewriteRule pattern matches against does not start with a slash.
This is also a 302 (temporary) redirect. Change this to 301 (permanent) redirect - if that is the intention - but only after you have tested that it's working OK. 301s are cached hard by the browser, so can make testing problematic.
You'll need to clear your browser cache before testing.
UPDATE: To match any digit you can change [23] to \d (the shorthand character class for digits. To match 1 or 2 digits, you can use \d{1,2}. For example:
RewriteRule ^reviews/page/\d{1,2}/$ /reviews/ [R=302,L]
You could use . (dot) to match any character. However, this might be too broad for what looks like a page number. Regular expressions (regex) should be as restrictive as possible.
I want to redirect all the unused link in my subdomain.olddomain.com to newdomain.com
i tried this but it doesn't seem to work for subdomain
RewriteCond %{HTTP_HOST} !^subdomain\.olddomain\.com [NC]
RewriteRule ^/(.*) http://www.newdomain.com/$1 [L,R=301]
I manage to make the code below but the issue is it does not redirect or catch all the unused like. It only redirects the root and returns page error when accessing unused link(e.g. tag) An example url look like below (OsCommerce)
sub.domain.com/product_info.php?products_id=999&osCsid=29f8a9504d1c4de90a1a1e4106344280
RewriteCond %{HTTP_HOST} !^www\.newdomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
Additional Info:
What I am trying to do is redirect all the link coming from subdomain.olddomain.com to newdomain.com so for example when someone visit subdomain.olddomain.com/tags/vanilla or subdomain.olddomain.com/product_info.php?products_id=999&osCsid=29f8a9504d1c4de90a1a1e4106344280m they will automatically be redirected to newdomain.com , the newdomain.com is located in another server server
From the documentation (emphasis mine):
Per-directory Rewrites
The rewrite engine may be used in .htaccess files and in sections, with some additional complexity.
To enable the rewrite engine in this context, you need to set "RewriteEngine On" and "Options FollowSymLinks" must be enabled. If
your administrator has disabled override of FollowSymLinks for a
user's directory, then you cannot use the rewrite engine. This
restriction is required for security reasons.
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is
automatically removed for the RewriteRule pattern matching and
automatically added after any relative (not starting with a slash or
protocol name) substitution encounters the end of a rule set. See the
RewriteBase directive for more information regarding what prefix will
be added back to relative substitutions.
If you wish to match against the full URL-path in a per-directory (htaccess) RewriteRule, use the %{REQUEST_URI} variable in a
RewriteCond.
The removed prefix always ends with a slash, meaning the matching occurs against a string which never has a leading slash. Therefore, a
Pattern with ^/ never matches in per-directory context.
Although rewrite rules are syntactically permitted in and sections (including their regular expression counterparts),
this should never be necessary and is unsupported. A likely feature to
break in these contexts is relative substitutions.
The .htaccess-file is per-directory context, so your rule will never ever match anything. Your rule should look like:
RewriteCond %{HTTP_HOST} !^subdomain\.olddomain\.com [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [L,R=301]
This is assuming that newdomain.com does not use this .htaccess file, as that would cause an infinite redirect.
I have a site with a folder, and a htaccess file within that folder. For the index.php file within that folder, I want to rewrite the querystring for a certain parameter, so that typing in this URL:
www.example.com/myfolder/myparameter
Behaves like this (ie makes $_GET['parameter'] = 'myparameter' in my code)
www.example.com/myfolder/index.php?parameter=myparameter
I have looked at many questions on StackOverflow, but have not managed to get this working. My code so far is
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*) [NC]
RewriteRule ^$ %0 [QSA]
But that just isn't working at all.
Please use this code
RewriteEngine on
RewriteRule (.*) index\.php?parameter=$1 [L,QSA]
RewriteEngine on
RewriteRule (^.*/)([^/]+)$ $1index\.php?parameter=$2 [L,QSA]
update
sorry use #somasundaram's answer. Per-directory .htaccess rewrite rules lose the directory prefix:
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the RewriteRule pattern matching and automatically added after any relative (not starting with a slash or protocol name) substitution encounters the end of a rule set. See the RewriteBase directive for more information regarding what prefix will be added back to relative substitutions.
(from the apache docs)