Many additional customizations are provided but are commented out, as they require careful consideration and sometimes may have unwanted repercussions.
Most of us do not realize that http://example.com
and http://www.example.com
are treated as two separate sites by search engines. You can either force rewriting of URLs to www or the non-www ones. I prefer the non-www URL, because it is three characters shorter!
HTML5 Boilerplate's .htaccess
file provides you with choices for doing either of them. By default, the configuration forces the server to rewrite requests for http://www.example.com
to http://example.com
. If you prefer the other way around, have the server rewrite requests for http://example.com
to http://www.example.com
, as described in the following steps:
# Option 1: # Rewrite "www.example.com -> example.com" <IfModule mod_rewrite.c> RewriteCond %{HTTPS} !=on RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC] RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] </IfModule>
# Option 1: # Rewrite "www.example.com -> example.com" # <IfModule mod_rewrite.c> # RewriteCond %{HTTPS} !=on # RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC] # RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] #</IfModule>
As you might notice, all we did was add a #
character and a space before each of those lines.
# Option 2: # To rewrite "example.com -> www.example.com" uncomment the following lines. # Be aware that the following rule might not be a good idea if you # use "real" subdomains for certain parts of your website. # <IfModule mod_rewrite.c> # RewriteCond %{HTTPS} !=on # RewriteCond %{HTTP_HOST} !^www..+$ [NC] # RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # </IfModule>
# Option 2: # To rewrite "example.com -> www.example.com" uncomment the following lines. # Be aware that the following rule might not be a good idea if you # use "real" subdomains for certain parts of your website. <IfModule mod_rewrite.c> RewriteCond %{HTTPS} !=on RewriteCond %{HTTP_HOST} !^www..+$ [NC] RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] </IfModule>
All we did was remove the #
character and a space in front of the lines starting with <IfModule mod_rewrite.c>
and ending with </IfModule>
.
Whichever option you want to use, make sure you don't have both these options enabled at the same time, as that would prevent Apache from serving your page.
IE usually blocks cookies set from within an IFrame. If you require such cookies to be set, especially if you have advertisements or social networking plugins, you need to send a Platform for Privacy Preferences Project (P3P) header.
Look for the comment in the .htaccess
file with the same text as the title of this section and change the following lines:
# <IfModule mod_headers.c> # Header set P3P "policyref="/w3c/p3p.xml", CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"" # </IfModule>
To the following code snippet:
<IfModule mod_headers.c> Header set P3P "policyref="/w3c/p3p.xml", CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"" </IfModule>
If you are serving PHP, there are a lot of configuration options in the HTML5 Boilerplate's .htaccess
file that could make your PHP installation more secure. If you are using PHP, you can turn them on using the same procedure as the one outlined in the section titled Suppress or force the "www."' at the beginning of URLs.
Given we aren't using PHP in our website, we do not need to turn them on.
You can prevent Apache from advertising its version to mitigate chances of malicious programmers exploiting vulnerabilities in a particular version. Here is how the Apache version is advertised:
This previous screenshot shows the Apache version number sent as a HTTP header to the browser.
This needs to be configured from within the server's main configuration file, and we cannot do this from within the .htaccess
file. So, let's remove the following directive from the HTML5 Boilerplate's .htaccess
file and replace the one found in /etc/apache2/httpd.conf
(the path to this file will be different if you are using Windows or Linux):
ServerTokens Prod
The following screenshot shows the version-less HTTP header sent by Apache after applying the configuration value to the Apache server's main configuration file:
Sometimes, you may want the server to combine multiple script or stylesheet files into one response when a request is made. Note that doing so does not make it any faster for your page to load, as the server takes its own time to stitch these files together.
This is an option I recommend you consider last, when every other solution has failed. Ideally, you should never be doing this.
To do this, first uncomment the following lines in the .htaccess
file from:
#<FilesMatch ".combined.js$"> # Options +Includes # AddOutputFilterByType INCLUDES application/javascript application/json # SetOutputFilter INCLUDES #</FilesMatch> #<FilesMatch ".combined.css$"> # Options +Includes # AddOutputFilterByType INCLUDES text/css # SetOutputFilter INCLUDES #</FilesMatch>
To the following code snippet:
<FilesMatch ".combined.js$"> Options +Includes AddOutputFilterByType INCLUDES application/javascript application/json SetOutputFilter INCLUDES </FilesMatch> <FilesMatch ".combined.css$"> Options +Includes AddOutputFilterByType INCLUDES text/css SetOutputFilter INCLUDES </FilesMatch>
Then, in the js
folder, create a file called script.combined.js
.
Open the script.combined.js
file in your text editor, and use the following syntax with all the files that should be combined and output in the script.combined.js
file:
# <!--#include file="<path/to/file.js>" --> # <!--#include file="<path/to/another-file.js>" -->
If you are looking to combine stylesheets on the fly, you can do the same. Create a file in the css
folder called style.combined.css
.
Open the style.combined.css
file in your text editor, and use the following syntax with all the files that should be combined and output in the style.combined.css
file:
# <!--#include file="<path/to/file.css " --> # <!--#include file="<path/to/another-file.css>" -->
As I mentioned earlier, doing this will make Apache slower to respond to these requests. You should be using a build script to concatenate files (we will look into the build script in Chapter 7, Automate Deployment with the Build Script). So uncomment this setting only if you have no other choice.
When you use background images that change on hovering over a link, you will see a flicker in IE when this occurs. You can prevent this by changing the following lines in the .htaccess
file from:
# BrowserMatch "MSIE" brokenvary=1 # BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1 # BrowserMatch "Opera" !brokenvary # SetEnvIfbrokenvary 1 force-no-vary
To the following code snippet:
BrowserMatch "MSIE" brokenvary=1 BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1 BrowserMatch "Opera" !brokenvary SetEnvIfbrokenvary 1 force-no-vary
If you want to serve your site only on a secured connection, you need to obtain a Secure Sockets Layer (SSL) certificate that browsers will use to identify your website. If the domain on the certificate does not match the domain on the incoming request—, for example, you had a SSL certificate for https://secure.example.com
, and the assets that are being loaded on the page hosted on that domain are served from https://example.com
, but all of the files are hosted on the same Apache server; —then browsers will throw warnings and inform the user that the authenticity of the Web page is unverifiable.
You can make sure the requests to domain, which does not have the SSL certificate, is rewritten to the one for which you do have an SSL certificate. If you require this, you can uncomment the following snippet from:
# <IfModule mod_rewrite.c> # RewriteCond %{SERVER_PORT} !^443 # RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L] # </IfModule>
To the following code snippet:
<IfModule mod_rewrite.c> RewriteCond %{SERVER_PORT} !^443 RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L] </IfModule>
Note that the https://example-domain-please-change-me.com
URL needs to point to the domain you have an SSL certificate for.
That covers all the optional features that HTML5 Boilerplate's .htaccess
file provides. Let us take a look at cross-domain policies and how to set them.
An HTTP request is called a cross-domain request when a page served from one domain, for example, http://example.com
, requires data from another, say http://foo.com
. By default, most browsers do not allow cross-domain requests of data–be it data or flash assets– to prevent malicious access.
However, you can set a cross-domain policy file on the server (in the previous example, the server where http://foo.com
is served from), which allows browsers to access these resources.
Flash requires this policy file to be specified in a file called crossdomain.xml
, where you can specify which domains can make request of assets from the server.
This file is provided within HTML5 Boilerplate, and by default, the most restrictive policy is enabled. If you do want the least restrictive policy, you can uncomment that option and comment away the most restrictive one.
You can also make cross-domain AJAX requests, or restrict access to images or fonts, by setting an HTTP header. This is known as the Cross Origin Resource Sharing (CORS) policy.
AJAX requests can only be made if the requesting page is on the same domain as the URL it is requesting data from. CORS is a new HTML5 feature that will allow you to make AJAX requests from any domain, provided permission has been given to the requesting domain. By setting an HTTP header on the server from which you are requesting data using an AJAX request, you can overcome this limitation. Let us look at how this can be done.
The following is an example of a cross-domain request that you could make:
var CORSRequest = new XMLHttpRequest(); CORSRequest.onload = function(e){ // Process returned data } CORSRequest.open('GET', 'http://nimbupani.com/data.json'), CORSRequest.send( null );
We note that the browser throws an error saying such access is forbidden, as shown in the following screenshot:
Now, in our .htaccess
file hosted on http://nimbupani.com, we will uncomment the following directive:
# <IfModule mod_headers.c> # Header set Access-Control-Allow-Origin "*" # </IfModule>
Let us try our code again. Aha! Now it works!
This is the least restrictive setting, which can allow any domain to make an AJAX request on your server. It is fairly trivial to make a very high volume of requests because of this and also to pretend it's your site and fool the visitors, and so on. Use this setting with care.
Typically, browsers allow all images to be linked from any other domain. This is called hotlinking. Read more about it at en.wikipedia.org/wiki/Inline_linking
. If a high-traffic website links to assets that are hosted on your server, your hosting provider might even fine you for excessive use of bandwidth (or your site might go down!). If you want to prevent this, for example, if you do not want http://example.com
to use an img
element with an src
attribute pointing to an image on your server http://foo.com/image.jpg
, you can enable a more restrictive policy that only allows certain domains to access your image files by changing the following line in the .htaccess
file from:
Header set Access-Control-Allow-Origin "*" env=IS_CORS
To the following line:
Header set Access-Control-Allow-Origin "http://example.com" env=IS_CORS
Where you replace http://example.com
with the domain name that is only allowed access to that image. The server will then prevent any other domain from accessing images on your domain.
If you want your images to be accessed by multiple domains, you will have to write a convoluted regex comparison for the origin, as shown in the following code snippet:
SetEnvIf Origin » "^http(s)?://(.+.)?(example-1.com|example-2.com)$" origin_is=$0 Header always set Access-Control-Allow-Origin %{origin_is}eenv=origin_is
In this case, replace example-1.com
with your domain (take care to place the forward slash before the .com
), and likewise for example-2.com
.
Most of the time, you will be hosting fonts on the same domain where you will be using them. If you do host fonts in a separate domain, Firefox will not request them without the right HTTP header. This directive is already enabled by default in .htaccess
file. In case you want to restrict access, you need to change these lines from:
<IfModule mod_headers.c>
<FilesMatch ".(ttf|ttc|otf|eot|woff|font.css)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
To the following code snippet:
<IfModule mod_headers.c>
<FilesMatch ".(ttf|ttc|otf|eot|woff|font.css)$">
Header set Access-Control-Allow-Origin "http://example.com"
</FilesMatch>
</IfModule>
Replace http://example.com
with the domain name you would like to specifically allow access to the Webfonts.