I am trying to create subdomains via htaccess. The code below does exactly want I want
It takes http://domain.com and redirect it to http://www.domain.com
Options -Indexes
DirectoryIndex index.html index.htm index.asp index.php
ErrorDocument 401 http://www.domain.com
ErrorDocument 403 http://www.domain.com
ErrorDocument 404 http://www.domain.com
ErrorDocument 500 http://www.domain.com
ErrorDocument 507 http://www.domain.com
RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain.com$
RewriteRule ^(.*) http://www.domain.com/$1 [QSA,L,R=301]
AddType text/html .html .htm .asp
This is the part I am not to sure of:
RewriteCond %{HTTP_HOST} ^domain.com/nl$
RewriteRule ^(.*) http://nl.domain.com/$1 [QSA,L,R=301]
How can I create virtual subdomains so that if someone goes to http://nl.domain.com it would stay on http://nl.domain.com if someone types http://www.nl.domain.com it would take out the http://www.nl.domain.com and make it http://nl.domain.com also the directory structure for the subdomain would be http://www.domain.com/nl (This is where the actual files will be sitting).
so if someone goes to http://www.domain.com/nl it should also redirect to http://nl.domain.com.
Thanks in advance for any advice and pointers
RewriteEngine on
# The ordering of the following rules is somewhat important
#
# External redirects with HTTP "301 - Moved Permanently" for subdomains
#
# Redirect www.nl.example.com to nl.example.com
RewriteCond %{HTTP_HOST} ^www\.nl\.example\.com$
RewriteRule ^(.*) http://nl.example.com/$1 [QSA,L,R=301]
# Instead I could do this to redirect any prefix before nl to nl.example.com
# RewriteCond %{HTTP_HOST} ^.+?\.nl\.example\.com$
# RewriteRule ^(.*) http://nl.example.com/$1 [QSA,L,R=301]
# Redirect www.foo.example.com to foo.example.com
RewriteCond %{HTTP_HOST} ^www\.foo\.example\.com$
RewriteRule ^(.*) http://foo.example.com/$1 [QSA,L,R=301]
# Instead I could do this to redirect any prefix before foo to foo.example.com
# RewriteCond %{HTTP_HOST} ^.+?\.foo\.example\.com$
# RewriteRule ^(.*) http://foo.example.com/$1 [QSA,L,R=301]
# Rewrite any remaining subdomains to example.com
RewriteCond %{HTTP_HOST} !^example\.com$
RewriteCond %{HTTP_HOST} !^nl\.example\.com$
RewriteCond %{HTTP_HOST} !^foo\.example\.com$
RewriteRule ^(.*) http://example.com/$1 [QSA,L,R=301]
# Assuming from this point forward we have either
# example.com, nl.example.com, or foo.example.com as the HTTP_HOST
# Redirect example.com/nl to nl.example.com
# (Note that ONLY example.com/nl is caught here.)
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^nl(/(.*))? http://nl.example.com/$2 [QSA,L,R=301]
# Redirect example.com/foo to foo.example.com
# (Note that ONLY example.com/foo is caught here.)
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^foo(/(.*))? http://foo.example.com/$2 [QSA,L,R=301]
#
# Internal rewrites for directory structuring
#
# Internal rewrite for the nl subdomain
# - Match the subdomain exactly
RewriteCond %{HTTP_HOST} ^nl\.example\.com$
# - Check to see if the rewrite already happened (prevent
# infinite loop of internal rewrites)
RewriteCond %{REQUEST_URI} !^/nl(/.*|$)
# - Rewrite the URL to the subdirectory
RewriteRule ^(.*) /nl/$1 [L]
# Internal rewrite for the foo subdomain
# - Match the subdomain exactly
RewriteCond %{HTTP_HOST} ^foo\.example\.com$
# - Check to see if the rewrite already happened (prevent
# infinite loop of internal rewrites)
RewriteCond %{REQUEST_URI} !^/foo(/.*|$)
# - Rewrite the URL to the subdirectory
RewriteRule ^(.*) /foo/$1 [L]
I haven't tested the above on a server, but I tested it on my local server, it should be close to what you need if I understood you correctly.
I'm sure you've seen the mod_rewrite docs. In addition to that, the Rewrite Guide and the Advanced Rewrite Guide have helpful practical examples.
Related
and thanks to read me.
My goal is to have the same htaccess code in local and production.
First, I need to rewrite example.com/index.php?action=somepage to example.com/somepage.
Second, I must rewrite http://example.com to https://example.com, but only in production, not on localhost.
So far this is my code:
RewriteEngine on
RewriteBase /
# For Ionos
RewriteRule ^([0-9a-zA-Z/\ -]+)(?:&([0-9a-zA-Z&=_\ -]+))?$ index.php?action=$1&$2
# $1 : route name and framework parameters
# $2 : classic $_GET parameters (¶m=value)
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,NE,R=301]
When I use https:// to connect, no problem, the first rule concerning index and action apply.
When I use http://, the adress become https://, BUT the index/action rule doesn't apply.
Thanks a lot!
Edit : this works :
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,R=301]
# For Ionos, http => https
RewriteRule ^([0-9a-zA-Z/\ -]+)(?:&([0-9a-zA-Z&=_\ -]+))?$ index.php?action=$1&$2
# $1 : route name and framework parameters
# $2 : classic $_GET parameters (¶m=value)
But I have a last problem.
My folder in like this:
[] example
...[]public
......htaccess
...htaccess
The code shown above is the htaccess of public directory. The htaccess of example directory redirect to public:
RewriteEngine on
RewriteBase /
# for Ionos
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
The problem is while http://example.com redirect to https://example.com, http://example.com/somepage redirect to https://example.com/public/somepage and I can't remove the "public" part.
Thanks!
Your two rules "were" in the wrong order. Your external redirect (HTTP to HTTPS) needs to be before the internal rewrite. Your first rule (rewrite) would have still applied, but it would have resulted in an external redirect to index.php?action=... (exposing your internal file/URL structure).
However, you are also missing L flags on both these rules.
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,R=301]
If this is in the /public/.htaccess file and the /public subdirectory is hidden (ie. it's being internally rewritten to) then you need to change the RewriteRule to read:
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
After the request is internally rewritten by the parent config, the REQUEST_URI server variable contains the full URL-path, including the "hidden" /public subdirectory, so if you redirect to REQUEST_URI it will expose the hidden subdirectory. Whereas, if you use a backreference to the matched RewriteRule pattern, which matches against a URL-path that is relative to the current directory then this naturally excludes the /public subdirectory.
First of all, I know there are lots of answers on this, but I don't actually find one that works. This is what I have in the .htaccess file right now, and I want to mention that it worked previously, but it does not anymore.
Redirect 301 /unt-de-cacao-de-plaja/filtre/producator/crisnatur/ /ingrijire-corporala/unt-cacao/unt-de-cacao-pentru-plaja-100g
Options +FollowSymlinks
# Prevent Directoy listing
Options -Indexes
# Prevent Direct Access to files
<FilesMatch "(?i)((\.tpl|\.ini|\.log|(?<!robots)\.txt))">
Require all denied
## For apache 2.2 and older, replace "Require all denied" with these two lines :
# Order deny,allow
# Deny from all
</FilesMatch>
# SEO URL Settings
RewriteEngine On
# If your opencart installation does not run on the main web folder make sure you folder it does run in ie. / becomes /shop/
RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=extension/feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=extension/feed/google_base [L]
RewriteRule ^system/download/(.*) index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
# FORCE HTTPS AND NON WWW
RewriteEngine on
RewriteCond %{ENV:HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
As a mention, I will have a lot of Redirect 301 from old pages to the new ones since the entire structure has been changed.
And the links that I am redirecting inside my website come with "www" like:
https://www.example.com/unt-de-cacao-de-plaja/filtre/producator/crisnatur/
and needs to be redirected to:
https://example.com/ingrijire-corporala/unt-cacao/unt-de-cacao-pentru-plaja-100g
Redirect to https and non-www
To instead redirect all requests to https and non-www, use the following code instead of the previous:
Canonical HTTPS/non-WWW
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1 [L,R=301]
</IfModule>
As before, place this code in the root .htaccess of your site. Here is what it's doing:
Checks if mod_rewrite is available
Checks if HTTPS is off, or if the request includes www
If either condition matches, the request qualifies and is redirected
to the https/non-www address
OR
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
A few issues, in order of importance:
You have your canonical HTTP to HTTPS and www to non-www redirects at the end of the file. By placing it at the end of the file, after your front-controller, it's simply never going to be processed for most requests. This needs to be near the start of the .htaccess file, before your front-controller.
You should avoid mixing redirects from both mod_alias (Redirect) and mod_rewrite (RewriteRule) in the same scope. Different modules execute at different times throughout the request, despite their apparent order in the config file. Since mod_rewrite is required for other redirects, you should convert the mod_alias Redirect directives to use RewriteRule instead.
For example:
RewriteRule ^unt-de-cacao-de-plaja/filtre/producator/crisnatur/$ /ingrijire-corporala/unt-cacao/unt-de-cacao-pentru-plaja-100g [R=301,L]
You should include the canonical scheme and hostname in your URL redirects in order to avoid multiple redirects when requesting an "old" URL at a non-canonical scheme ot hostname.
For example:
RewriteRule ^unt-de-cacao-de-plaja/filtre/producator/crisnatur/$ https://example.com/ingrijire-corporala/unt-cacao/unt-de-cacao-pentru-plaja-100g [R=301,L]
Depending on what you mean exactly by "a lot of Redirect 301" - you should not be doing this at all in .htaccess and instead redirecting in your server-side script, once you have determined that the request will 404. This is to prioritise normal site visiters and not your redirects (that get executed on every single request).
RewriteCond %{ENV:HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
Since you stated that these directives worked previously then I assume the use of the HTTPS environment variable is OK on your system. But note that, whilst this is relatively common, it's non-standard. (It implies the server is using some kind of SSL front-end/proxy.)
Note that the order of these rules will result in a double redirect when requesting http://www.example.com/<anything> (HTTP + www). Which is necessary if you are implementing HSTS, but otherwise, you should reverse these two rules to avoid this unnecessary double redirect.
I've looked through tens of articles regarding this but none of them has solved my issue and it continues to give me a headache.
Here's what I want to achieve:
1) I have an second domain name which needs redirecting to the main domain while keeping the rest of the URL,
2) All files should lose .php extension,
3) Force WWW,
4) Force HTTPS.
Now the problem is that my current .htaccess only works this way for the main domain and only if the WWW condition is met. Let me explain.
If I type in domain1.com/page or domain2.com/page, it will open https:// www.domain1/2.com/page.php but it should only be /page without .php.
If I type in www.domain1.com/page, it will open https:// www.domain1.com/page - Expected behaviour,but if I type in www.domain2.com/page, it will open https:// domain1.com/page.php.
How can I make sure that any conbination of HTTP/HTTPS and WWW/non-WWW, domain1.com/domain2.com always redirects to https:// www.domain1.com/page ?
I'm also happy for any php code suggestions that I might put the top of every .php file to automatically redirect to the extensionless version but would really love to understand why my .htaccess isn't working.
Here's the code:
## Main Rules
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
## Redirect Domain2.com to Main
RewriteCond %{HTTP_HOST} ^www\.domain2\.com [NC]
RewriteRule ^(.*)$ https://www.domain1.com/$1 [R,L]
## Remove .php Extensions
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
## Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
## Force WWW
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
ErrorDocument 404 /404
Thanks a lot!
You have the directives in the wrong order. Importantly, the rule that appends the .php extension via an internal rewrite (which you've labelled "Remove .php Extensions") should go at the end, after the external redirects. Your rewrite is appending .php to the requested URL, ie. page becomes page.php and then you are triggering an external redirect which naturally exposes the underlying filename.
However, your directives will result in multiple redirects and can be simplified. The last redirect, for instance, does not canonicalise the protocol (and replies on previous rules to have done this).
For example:
ErrorDocument 404 /404
## Main Rules
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
## Redirect Domain2.com to Main
RewriteCond %{HTTP_HOST} ^(www\.)?domain2\.com [NC]
RewriteRule (.*) https://www.domain1.com/$1 [R,L]
## Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
## Force WWW
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
## Append .php Extensions
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*) $1.php [L]
If you have no intention of implementing HSTS then you should reverse the "Force HTTPS" and "Force WWW" rules in order to avoid an additional redirect when requesting http://domain1.com/page.
Note that your initial redirect from domain2.com to domain1.com is a 302 (temporary) redirect.
UPDATE: Note that MultiViews should also be disabled, if not already. For example:
Options +FollowSymLinks -MultiViews
If MultiViews was enabled, then this would also result in the first redirect exposing the file extension since mod_negotiation would issue an internal subrequest for page.php before mod_rewrite processes the request. However, if MultiViews was enabled, then this would also mean that your final rewrite rule that appends the .php extension was effectively being bypassed (since the 2nd conditon would always fail, unless page.php.php existed.).
With MultiViews disabled then this highlights a potential bug with the final rewrite. In that a request for /page/foo, where /page.php exists as an actual file (as in your example) would result in a 500 internal server error due to a rewrite loop. To correct this, the final rewrite rule that appends the .php extension should be changed to the following:
## Append .php Extensions
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]
(There's no need to check that the request is not a directory and is a file, since it can never be both.)
I am trying to get a URL shortener to work.
Instead of redirecting the link : http://urlshortner.com/33 to, say, yahoo.com, it just redirects it to http://urlshortner.com/yahoo.com.
But if I put the info from that .htaccess file that resides in my shortener subdir onto my MAIN .htaccess file (root level) the URL shortner redirect works correctly, but my MAIN page gives a 404 error.
Example:
I have many URLs on my server and my MAIN site on my server root.
So, my URL shortener is located at:
myserver/urlshortner which points to urlshortner dot com
and my main page is:
myserver/index.html which points to mymainpage dot com
I have an .htacess file at myserver/urlshortner/.htaccess that says:
RewriteEngine on
RewriteCond %{request_filename} -f
RewriteRule ^(.*) $1 [L]
RewriteRule ^(([^/]*)+)(/([^/]{0,32})(/.+)?)?$ index.php?a=$1&q=$3 [L]
And my .htacess file at my root directory that forces all requests to https etc:
# Begin IP blocking #
Order Allow,Deny
Deny from xxx.xx.xxx
Allow from all
# End IP blocking #
RewriteEngine On
RewriteCond %{HTTP_HOST} ^XXXXXX\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.XXXXXX.com/$1 [R,L]
AddType application/xspf+xml .xspf .xspf
BUT, when I combine them like this:
# Begin IP blocking #
Order Allow,Deny
Deny from xxx.xx.xxx
Allow from all
# End IP blocking #
RewriteEngine On
RewriteCond %{HTTP_HOST} ^XXXXXX\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.XXXXXX.com/$1 [R,L]
RewriteCond %{request_filename} -f
RewriteRule ^(.*) $1 [L]
RewriteRule ^(([^/]*)+)(/([^/]{0,32})(/.+)?)?$ index.php?a=$1&q=$3 [L]
AddType application/xspf+xml .xspf .xspf
The URL shortener works, but my main page gives a 404 error.
Any thoughts on this?
I have my htaccess file setup, so that the pages remove extensions. Now, I am trying to make the pages that transfer variables, into SEO friendly urls ... so, for example...
http://www.example.com/art-gallery?page=2 ... which is actually "art-gallery.php?page=2", would turn into... http://www.example.com/art-gallery/page/2
Or... http://www.example.com/art-piece?id=3 ...would go to... http://www.example.com/art-piece/id/3
... and so on ...
I have alot in my htaccess file, and am not sure how to do the above (there are plenty of tutorials on going from www.example.com/index.php?page=2 to www.example.com/page/2/ but none that do exactly what I need). Ideally, I'd like to be able to do this for all similar pages...
# enable the rewrite engine
RewriteEngine On
# Set your root directory
RewriteBase /
# Force www:
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301,NC]
# Remove the .php extension
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# Remove index and reference the directory
RewriteRule (.*)/index$ $1/ [R=301]
# Remove trailing slash if not a directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# Forward request to html file, **but don't redirect (bot friendly)**
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
# Disable Directory Browsing
Options -Indexes
# Disable Hotlinking of Images
# with forbidden or custom image option
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?google.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ – [NC,F,L]
# Protect htaccess File
<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</files>
You can transfer parameters with the variable QUERY_STRING.
Consider the following rule:
RewriteRule ^index.html index.php?%{QUERY_STRING}&m=main&a=index
This rule would transform
index.html?something=value
into
index.php?something=value&m=main&a=index
You should use the RewriteEngine.
You could also use a 301 redirect either alone or in conjunction with the RewriteEngine to redirect SEs.
Generally, though redirecting SEs to a different page than what users will see is not a good practice, and may result in your pagerank decreasing. Instead, try migrating all your pages to the second URL format, and consider using 301 redirects to help the transition.
Generally: Use 301 redirects for SE-friendly page changes. See this SO for additional reference.
You can insert this rule just before Forward request to html file rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/])/([^/])/([^/])/?$ $1.php?$2=$3 [L,QSA]
This is quite old but why not do the following:
RewriteEngine On
RewriteRule ^([^?]*) index.php?route=$1 [L,QSA]
Then in your index.php you can handle it like such;
if (isset($_GET['route'])) {
$route = explode('/', $_GET['route']);
if (iconv_strlen((end($parts)), 'UTF-8') == 0) {
array_pop($parts);
}
}
From here your main level would be handled with $route[0], second level $route[1]
For example;
http://example.com/art-gallery/2
$route[0] would equal 'art-gallery'
$route[1] would equal '2'