Community Post

Only allow supported web browsers using JavaScript

marncz

Introduction

There are few reasons why you may want to include web browsers checks in your web app: caring about user experience, gathering stats about users' habits based on web browsers, give a notice on slightly outdated web browsers or even block the access for really old browsers. This tutorial will show how to create a simple check to ensure that our users are using software that meets our application's requirements.

You can see finished product here.

User Agents

First of all we need to understand what an user agent is, it is a parameter that is passed as one of the headers when requesting a resource on our page, we will use it to get web browser name and its version. Below is a sample User Agent string that tells us some information about the user:

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36

Above string can tell us that user is viewing our website on Linux and using Chrome 48.0 which is also compatible with Safari in version 537 ( they share similar capabilities when it comes to CSS processing ).


Note: user agent is very easy to spoof ( send modified string ) e.g. by using a web browser extension

Creating a function

We need to start our work by creating a function that will be a guard which lets in only supported versions of web browsers.

Our function will have one argument, rules in this format: { "Chrome" : 48, "Firefox" : 33 }, which means that only allow people who are using these, or newer version of either Chrome or Firefox to access our page

 browserDepCheck = function ( rules )
 {

 }

Getting user's web browser info

Next step will be to split the string we receive from JavaScript's built-in function into a format e.g. "Chrome 48", we use below code. We need to take slightly different approach when it come to Microsoft's Internet Explorer:

 if( window.MSStream )
 {
           var agentString = window.MSStream;
           var array = agentString.split( ";" );   
 } else {
               var userAgent =  navigator.userAgent;

          if( userAgent.includes("MSIE") )
          {
                var array = userAgent.split( ';' );
          } else {
                var array = userAgent.split( ',' );
          }
 }

Our goal after this step is to have two variables: browser and version to make our lives easier

for( var i = 0; i < array.length; i++ ){
         for ( var key in rules ) {

             var string =  array[i].substring(array[i].indexOf( key ));
              if( string.includes( "MSIE" ) )
               {
                var browser = string.split(' ')[0];
                   var version = parseInt(string.split(' ')[1]);
               }  else {
                   var browser = string.split('/')[0];
                   var version = parseInt( string.split('/')[1] );
              }

                if( browser.includes( key ) )
               {
                         if( version <= rules[key] ){
                                    failedDependencies++;
                          }
                 }
          }
}

Letting users know when their browser is not supported

We should let our users know when they are using an outdated version, we can do that by accessing the failedDependencies variable we can determine if any dependencies error occurred during the check and if our user meets the requirements.

Now we can display a warning that informs users that they should update their web browser, or it can redirect users to another url, which can block access to our web app:

if ( failedDependencies > 0 )
{
       window.location.href = "/old-browser";
}

Finish our function

At the end of the function we should add below line so it returns a boolean:

if ( failedDependencies > 0 )
{
     return false; 
} else {
        return true; 
}

This way we can call the function browserDepCheck on any other page of our application, let's say in our website's html header or footer which is included in every page:

var minVersionBrowser = browserDepCheck( {  "Chrome" : 48 } );
if( !minVersionBrowser )
{
    alert ( "Please conside updating your web browser" );
}

Another approach can be creating a popup that shows icons and links allowing users download the newest version of the most popular browsers:

var showPopup = function ()
{ 
   document.documentElement.innerHTML += '\
      <div id="popup"> \
      <h1> Upss... </h1> \
      Your web browser does not meet minimal requirements to view this website.<br> \
      Consider upgrading your current web browser or downloading one of the below web browsers in the latest version. \
      <div style="margin-left:12%;position: absolute;bottom: 10%;"> \
      <a href="https://www.google.com/chrome/browser/desktop/index.html" target="_blank"><img src="images/chrome.png" style="margin-left:10px;height:90px"></a> \
      <a href="https://www.mozilla.org/firefox/new/" target="_blank"><img src="images/firefox.png" style="margin-left:10px;height:90px"> </a>\
      <a href="http://www.opera.com/download" target="_blank"><img src="images/opera.png" style="margin-left:10px;height:90px"> </a>\
      <a href="https://www.microsoft.com/en-gb/download/internet-explorer.aspx" target="_blank"><img src="images/ie.png" style="margin-left:10px;height:90px"> </a>\
      </div></div>';
}
#popup {
        position: absolute;
        top: 20%;
        left: 25%;
        margin-top: -50px;
        margin-left: -50px;
        width: 60%;
        height: 60%;
        background-color:#003E59;
        color: white;
        opacity:1.0 !important;
        text-align:center;
        padding:5%;
        font-family: Georgia, serif;
        border-radius:10px;
}

Determining required version

But how can we determine the lowest version number supported by our website? Looking at this table we can see a list of CSS rules with minimum supported version. Our plan is to:

  1. Get all CSS rules for current page
  2. Create of list of all rules from above table along with dependencies
  3. Make a new function to return minimum version
  4. Check against the list of dependencies we made
  5. Return the lowest version that meets all of the CSS rules' requirements on our page

Get all CSS rules

In this step we need to create our second function called getMinBrowserVersion which accepts a string e.g "MSIE", "Chrome, "Firefox" etc. it will return min. version allowed to see our app:

var getMinBrowserVersion = function ( browser )
{

}

We are going to generate an array of all the CSS rules that are used on our web page:

var allCSSRules = getComputedStyle( document.body );

Create a list of dependencies

I have generated a list of all required version based on the CSS3 table, few entries are listed below, you can view the full list on the GitHub page, you would need to generate this list only once and update it as you find more dependencies, and even add your own ones:

var rules = {
"align-content" : [11,28,21,9,12.1], 
"align-items" : [11,20,21,9,12.1]
[...]
}

Format for above list is "CSS_name" : [IE_version, Firefox_version, Chrome_version, Safari_Version, Opera_version]

Return required version

At the top of the function we also declare order of rules in our list as described in the format section:

    if( browser == "MSIE" )              { var index = 0; }
    else if( browser == "Firefox" )    { var index = 1; }
    else if( browser == "Chrome" )  { var index = 2; }
    else if( browser == "Safari" )     { var index = 3; }
    else if( browser == "Opera" )     { var index = 4; }

    var browsers = [
                    "MSIE",
                    "Firefox",
                    "Chrome",
                    "Safari",
                    "Opera"
                      ]; 

Next step is to check against our array of all CSS rules what version number is the lowest supported for all of them:

var minVersion = 0;
for ( var key in rules ) {

         for (var x = 0; x < allCSSNames.length; x++)
           {
            if( allCSSNames[x] == key ){
              if( rules[key][index] > minVersion ) 
                  { 
                       console.log( key + " may not work properly on " + browsers[index] + " < " + rules[key][index] );
                        minVersion = rules[key][index];
                  }            
           }
     }

   }

return minVersion;

This function will return minimal version that will meet all of page's CSS.


If any CSS rule required higher browser's version it will log a message to the console: animation-name may not work properly on Chrome < 43

Final touches

Now we can achieve many different scenarios combining two functions we just created, one usage is as follows:

var chromeMin = getMinBrowserVersion( "Chrome" );
var passedVersionCheck = browserDepCheck ( { "Chrome" : chromeMin, } );

if ( ! passedVersionCheck )
{
    alert ( " Please consider updating your web browser" );
}

We managed to check the minimum version required to see the full potential of our website and then check if user is using supported browser's version.

This project can be expanded to include more checks, it will help to create better user experience and lower number of complaints that something is not compatible with user's browser, in most cases they do know whether their software is outdated and how to update it.

That’s all folks!

We made it! You can see the demo here, send any suggestions my way!