'How to know if browser has PDF viewer or not?

I am viewing PDF into iframe. It works fine. But some of the client don't able to see it in IE. They get it as download option.

How can I identify if browser has pdf viewer or not and prompt user that he hasn't pdf viewer?

Note: I am using asp.net mvc 5 (c#).

I tried this, but don't help me. The problem with me some of the client has Adobe PDF, so no issue for below answer. But those who have nitropdf or chrome pdf viewer, below answer don't help me. I want to idenitify all pdf viewer. otherwise if client has some kind of pdf viewer then also alert will be display that no pdf viewer is installed. And that's wrong thing.

I applied this code by getting help from عبد النور التومي's answer and it worked for chrome and mozilla. Here is the js I modified.

But IE still not respond to it. I don't know how to check in IE that it has pdf viewer or not. For IE, I'm getting following error though there is pdf viewer is there:

enter image description here



Solution 1:[1]

I tried following solution by taken help from ??? ????? ??????, which helps for any pdf viewer in chrome and mozilla

    var getAcrobatInfo = function () {

        var getBrowserName = function () {
            return this.name = this.name || function () {
                var userAgent = navigator ? navigator.userAgent.toLowerCase() : "other";

                if (userAgent.indexOf("chrome") > -1) { return "chrome"; }
                else if (userAgent.indexOf("safari") > -1) { return "safari"; }
                else if (userAgent.indexOf("msie") > -1 || userAgent.indexOf("trident") > -1) { return "ie"; }
                else if (userAgent.indexOf("firefox") > -1) { return "firefox";}
                return userAgent;
            }();
        };

        var getActiveXObject = function (name) {
            try { return new ActiveXObject(name); } catch (e) { }
        };

        var getNavigatorPlugin = function (name) {
            try {
                for (key in navigator.plugins) {
                    var plugin = navigator.plugins[key];
                    if (plugin.name.toLowerCase().indexOf(name) > -1) { return plugin; }
                }
            } catch (e) {

            }

        };

        var getPDFPlugin = function () {
            return this.plugin = this.plugin || function () {
                if (getBrowserName() == 'ie') {
                    return getActiveXObject('AcroPDF.PDF') || getActiveXObject('PDF.PdfCtrl');
                }
                else {
                    return getNavigatorPlugin('adobe acrobat') || getNavigatorPlugin('pdf') || getNavigatorPlugin('foxit reader');  // works for all plugins which has word like 'adobe acrobat', 'pdf' and 'foxit reader'.
                }
            }();
        };

        var isAcrobatInstalled = function () {
            return !!getPDFPlugin();
        };

        var getAcrobatVersion = function () {
            try {
                var plugin = getPDFPlugin();

                if (getBrowserName() == 'ie') {
                    var versions = plugin.GetVersions().split(',');
                    var latest = versions[0].split('=');
                    return parseFloat(latest[1]);
                }

                if (plugin.version) return parseInt(plugin.version);
                return plugin.name

            }
            catch (e) {
                return null;
            }
        };

        return {
            browser: getBrowserName(),      // Return browser name
            acrobat: isAcrobatInstalled() ? true : false,   // return pdf viewer is enabled or not
            acrobatVersion: getAcrobatVersion()  // reurn acrobat version for browser


   };
}

And I got following error for IE, Though I have pdf viewer installed in my browser.: enter image description here

Then I solved it by this link.

Then I add new condition for IE 11 trident and now it works fine. Also I added option to check for foxit reader. you can add another pdf reader name also in or condition.

Solution 2:[2]

There is a JS solution :

var hasPdfViewer = getAcrobatInfo().acrobat ==="installed";

Known that API getAcrobatInfo is :

// http://thecodeabode.blogspot.com
// @author: Ben Kitzelman
// @license:  FreeBSD: (http://opensource.org/licenses/BSD-2-Clause) Do whatever you like with it
// @updated: 03-03-2013

var getAcrobatInfo = function() {

  var getBrowserName = function() {
    return this.name = this.name || function() {
      var userAgent = navigator ? navigator.userAgent.toLowerCase() : "other";

      if(userAgent.indexOf("chrome") > -1)        return "chrome";
      else if(userAgent.indexOf("safari") > -1)   return "safari";
      else if(userAgent.indexOf("msie") > -1)     return "ie";
      else if(userAgent.indexOf("firefox") > -1)  return "firefox";
      return userAgent;
    }();
  };

  var getActiveXObject = function(name) {
    try { return new ActiveXObject(name); } catch(e) {}
  };

  var getNavigatorPlugin = function(name) {
    for(key in navigator.plugins) {
      var plugin = navigator.plugins[key];
      if(plugin.name == name) return plugin;
    }
  };

  var getPDFPlugin = function() {
    return this.plugin = this.plugin || function() {
      if(getBrowserName() == 'ie') {
        //
        // load the activeX control
        // AcroPDF.PDF is used by version 7 and later
        // PDF.PdfCtrl is used by version 6 and earlier
        return getActiveXObject('AcroPDF.PDF') || getActiveXObject('PDF.PdfCtrl');
      }
      else {
        return getNavigatorPlugin('Adobe Acrobat') || getNavigatorPlugin('Chrome PDF Viewer') || getNavigatorPlugin('WebKit built-in PDF');
      }
    }();
  };

  var isAcrobatInstalled = function() {
    return !!getPDFPlugin();
  };
  var getAcrobatVersion = function() {
    try {
      var plugin = getPDFPlugin();

      if(getBrowserName() == 'ie') {
        var versions = plugin.GetVersions().split(',');
        var latest   = versions[0].split('=');
        return parseFloat(latest[1]);
      }
      if(plugin.version) return parseInt(plugin.version);
      return plugin.name
    }
    catch(e) {
      return null;
    }
  }

  // The returned object
  return {
    browser:        getBrowserName(),
    acrobat:        isAcrobatInstalled() ? 'installed' : false,
    acrobatVersion: getAcrobatVersion()
  };
};

Solution 3:[3]

As an alternative, you can use a library like viewer.js to display your pdf in a container.

see http://viewerjs.org/

Solution 4:[4]

PDF format is a licensed adobe format, from my understanding it's probably not always going to be reliable detection if you need to account for all non-licensed PDF readers also.

However, there is this resource: http://www.pinlady.net/PluginDetect/PDFReader/

The basic idea is:

  • Detect all plugins running in the browser
  • Search for "application/pdf" in the browser's navigator.mimeTypes array
  • If the navigator.mimeTypes array test fails, a second test is run in the background (i.e. nothing shown to the user on the frontend) which sends the browser a lightweight "empty" pdf file to see if it can be interpreted

Of course the idea of running a test pdf in the background might be a costly solution (i.e. mobile users on 3G etc.) but it's probably going to be a pretty reliable method, and the good part is you only have to test your user once when they reach your domain and then set a cookie or localStorage item with their pdf config saved so you don't have to keep testing their pdf capability.

Solution 5:[5]

I think it can be check from the navigator MimeType

function isSupportPDF() {
    var hasPDFViewer = false;
    try {
        var pdf =
            navigator.mimeTypes &&
            navigator.mimeTypes["application/pdf"]
                ? navigator.mimeTypes["application/pdf"].enabledPlugin
                : 0;
        if (pdf) hasPDFViewer = true;
    } catch (e) {
        if (navigator.mimeTypes["application/pdf"] != undefined)
            hasPDFViewer = true;
    }

    return hasPDFViewer;
}

Solution 6:[6]

A newer method is to use Navigator.pdfViewerEnabled:

const haveViewer = navigator.pdfViewerEnabled || false;

It is in April 2022 only supported in 67% of used browsers, but will eventually replace the deprecated navigator.mimeTypes method.

HTML specification

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Dhwani
Solution 3 Julien R
Solution 4
Solution 5 Irfan Soetedja
Solution 6 Mattias Wallin