5

Is there something built into Coldfusion that would let me know the browser and version number surfing my site? Are there existant libraries that would enable me to do this?

My google-fu hasn't shown many things other than simple if statements detecting IE.

I did do a dump of the cgi.http_user_agent variable in Chrome:

Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.77 Safari/534.24

There's three different browsers mentionned in there! Doing an if statement looking for either would return true. There's got to be a more formal approach?

James A Mohler
  • 11,060
  • 15
  • 46
  • 72
TechFanDan
  • 3,329
  • 6
  • 46
  • 89
  • 1
    [Thou shalt not be browser sniffing](http://stackoverflow.com/questions/661213/why-is-browser-sniffing-so-bad). – Tomalak Jun 09 '11 at 15:02
  • 1
    Agreed. I'm just trying to replicate a JS component in Coldfusion. Browser sniffing is only a tiny part of what it does. – TechFanDan Jun 09 '11 at 15:28
  • That isn't actually saying three browsers. The AppleWebKit part just says that you are using a browser built on the WebKit rendering engine (the Safari part is saying the same thing). I have never been sure what the Mozilla part is, but the only part telling you a browser is Chrome and the version it is on. When checking for Chrome you may just want to check for AppleWebKit since most webkit browsers will support the same stuff. – Dave Long Jun 09 '11 at 15:56

8 Answers8

5

This is much easier than the complicated function submitted earlier...

<CFIF FindNoCase('Chrome','#CGI.HTTP_USER_AGENT#') GREATER THAN 0>
  <CFSET browser = 'Chrome'>
</CFIF>

credit: http://www.paulsilver.co.uk/code/coldfusion_detect_browser.php

Klog
  • 109
  • 1
  • 7
4

Could you not use javascript instead? http://cssuseragent.org/

CSSUA is awesome, adds simple classes to the tag and allows you to target content in CSS/Javascript using classes like ua-ie-6 etc

Jon Joyce
  • 213
  • 1
  • 11
3

There is a User-Defined Function which can parse out the user_agent string.

browserDetect

<cfscript>
/**
 * Detects 130+ browsers.
 * v2 by Daniel Harvey, adds Flock/Chrome and Safari fix.
 * 
 * @param UserAgent      User agent string to parse. Defaults to cgi.http_user_agent. (Optional)
 * @return Returns a string. 
 * @author John Bartlett (jbartlett@strangejourney.net) 
 * @version 4, June 28, 2009 
 */
function browserDetect() {

// Default User Agent to the CGI browser string
var UserAgent=CGI.HTTP_USER_AGENT;

// Regex to parse out version numbers
var VerNo="/?v?_? ?v?[\(?]?([A-Z0-9]*\.){0,9}[A-Z0-9\-.]*(?=[^A-Z0-9])";

// List of browser names
var BrowserList="";

// Identified browser info
var BrowserName="";
var BrowserVer="";

// Working variables
var Browser="";
var tmp="";
var tmp2="";
var x=0;


// If a value was passed to the function, use it as the User Agent
if (ArrayLen(Arguments) EQ 1) UserAgent=Arguments[1];

// Allow regex to match on EOL and instring
UserAgent=UserAgent & " ";

// Browser List (Allows regex - see BlackBerry for example)
BrowserList="1X|Amaya|Ubuntu APT-HTTP|AmigaVoyager|Android|Arachne|Amiga-AWeb|Arora|Bison|Bluefish|Browsex|Camino|Check&Get|Chimera|Chrome|Contiki|cURL|Democracy|" &
            "Dillo|DocZilla|edbrowse|ELinks|Emacs-W3|Epiphany|Galeon|Minefield|Firebird|Phoenix|Flock|IceApe|IceWeasel|IceCat|Gnuzilla|" &
            "Google|Google-Sitemaps|HTTPClient|HP Web PrintSmart|IBrowse|iCab|ICE Browser|Kazehakase|KKman|K-Meleon|Konqueror|Links|Lobo|Lynx|Mosaic|SeaMonkey|" &
            "muCommander|NetPositive|Navigator|NetSurf|OmniWeb|Acorn Browse|Oregano|Prism|retawq|Shiira Safari|Shiretoko|Sleipnir|Songbird|Strata|Sylera|" &
            "ThunderBrowse|W3CLineMode|WebCapture|WebTV|w3m|Wget|Xenu_Link_Sleuth|Oregano|xChaos_Arachne|WDG_Validator|W3C_Validator|" &
            "Jigsaw|PLAYSTATION 3|PlayStation Portable|IPD|" &
            "AvantGo|DoCoMo|UP.Browser|Vodafone|J-PHONE|PDXGW|ASTEL|EudoraWeb|Minimo|PLink|NetFront|Xiino|";
            // Mobile strings
            BrowserList=BrowserList & "iPhone|Vodafone|J-PHONE|DDIPocket|EudoraWeb|Minimo|PLink|Plucker|NetFront|PIE|Xiino|" &
            "Opera Mini|IEMobile|portalmmm|OpVer|MobileExplorer|Blazer|MobileExplorer|Opera Mobi|BlackBerry\d*[A-Za-z]?|" &
            "PPC|PalmOS|Smartphone|Netscape|Opera|Safari|Firefox|MSIE|HP iPAQ|LGE|MOT-[A-Z0-9\-]*|Nokia|";

            // No browser version given
            BrowserList=BrowserList & "AlphaServer|Charon|Fetch|Hv3|IIgs|Mothra|Netmath|OffByOne|pango-text|Avant Browser|midori|Smart Bro|Swiftfox";

            // Identify browser and version
Browser=REMatchNoCase("(#BrowserList#)/?#VerNo#",UserAgent);

if (ArrayLen(Browser) GT 0) {

    if (ArrayLen(Browser) GT 1) {

        // If multiple browsers detected, delete the common "spoofed" browsers
        if (Browser[1] EQ "MSIE 6.0" AND Browser[2] EQ "MSIE 7.0") ArrayDeleteAt(Browser,1);
        if (Browser[1] EQ "MSIE 7.0" AND Browser[2] EQ "MSIE 6.0") ArrayDeleteAt(Browser,2);
        tmp2=Browser[ArrayLen(Browser)];

        for (x=ArrayLen(Browser); x GTE 1; x=x-1) {
            tmp=Rematchnocase("[A-Za-z0-9.]*",Browser[x]);
            if (ListFindNoCase("Navigator,Netscape,Opera,Safari,Firefox,MSIE,PalmOS,PPC",tmp[1]) GT 0) ArrayDeleteAt(Browser,x);
        }

        if (ArrayLen(Browser) EQ 0) Browser[1]=tmp2;
    }

    // Seperate out browser name and version number
    tmp=Rematchnocase("[A-Za-z0-9. _\-&]*",Browser[1]);

    Browser=tmp[1];

    if (ArrayLen(tmp) EQ 2) BrowserVer=tmp[2];

    // Handle "Version" in browser string
    tmp=REMatchNoCase("Version/?#VerNo#",UserAgent);

    if (ArrayLen(tmp) EQ 1) {
        tmp=Rematchnocase("[A-Za-z0-9.]*",tmp[1]);
        BrowserVer=tmp[2];
    }

    // Handle multiple BlackBerry browser strings
    if (Left(Browser,10) EQ "BlackBerry") Browser="BlackBerry";

    // Return result
    return Browser & " " & BrowserVer;

}

// Unable to identify browser
return "Unknown";

}
</cfscript>
ale
  • 6,369
  • 7
  • 55
  • 65
  • 1
    It will, of course, start to fail if new strings are not added as new browsers come out. – ale Jun 09 '11 at 15:34
  • 1
    I gave +1 to this as it does what the OP intends, but it's nothing I would rely on, generally speaking. – Tomalak Jun 09 '11 at 15:38
  • I just tried the above 7 year old UDF and it returned "Chrome 42" for an Edge useragent. Have there been any updates since 2011? As a result, I switched to BrowscapCFC & cached lookup results (for performance) as the BrowsCap.org website keeps the database updated and provides more information (platform, crawler, table, mobile, etc) – James Moberg Oct 31 '18 at 17:14
1

I created BrowscapCFC powered by http://browscap.org/. It may fit your needs

Henry
  • 32,689
  • 19
  • 120
  • 221
1

Here is refactored (from above) cfscript version for just browser name

function GetBrowserName() {
    var rs = "Unknown";
    var uag = cgi.HTTP_USER_AGENT;
    if (FindNoCase("Opera",uag))
         rs = "Opera";
    else if (FindNoCase("OPR",uag))
         rs = "Opera";
    else if (FindNoCase("Edge",uag))
         rs = "Edge";
    else if (FindNoCase("Chrome",uag))
         rs = "Chrome";
    else if (FindNoCase("Safari",uag))
         rs = "Safari";
    else if (FindNoCase("Firefox",uag))
         rs = "Firefox";
    else if (FindNoCase("MSIE",uag))
         rs = "IExplore";
    else if (FindNoCase("Trident",uag))
         rs = "IExplore";
    else
         rs = "Unknown";
    return rs;
}
Nathan
  • 41
  • 3
0

The user defined function above worked great, but I had to add the following code to get the version number to work correctly with IE (MSIE):

// Handle MSIE Version issue
IF (Left(Browser,4) EQ "MSIE") {
        tmpBrowser = Browser;
    IF (listLen("#tmpBrowser#", " ") EQ 2) {
        Browser = listGetAt("#tmpBrowser#", 1, " ");
        BrowserVer = listGetAt("#tmpBrowser#", 2, " ");
    }
}

With a user_agent like this:

Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)

It was returning a blank version and a browser name of "MSIE 8.0"

  • IE11 makes things even more interesting. [Apparently it no longer reports MSIE](https://msdn.microsoft.com/library/bg182625%28v=vs.110%29.aspx). – Leigh Aug 24 '15 at 23:09
0

Here is a recent build of the browser name and version Tested on Opra / IE 8 / IE 9 / IE 10 / IE 11 / Edge / Chrome / Firefox

<cffunction name="GetBrowser" access="public">
    <cfset var l = {}>
    <cfset l.UserInfo = cgi.HTTP_USER_AGENT>
    <cfset l.Browser = {}>

    <cfif FindNoCase ( "Opera", l.UserInfo ) >
        <cfset l.Browser.type = "Opera">
        <cfset l.Browser.Name = "Opera">
    <cfelseif FindNoCase ( "OPR", l.UserInfo )>
        <cfset l.Browser.type = "OPR">
        <cfset l.Browser.Name = "Opera">
    <cfelseif FindNoCase ( "Edge", l.UserInfo )>
        <cfset l.Browser.type = "Edge">
        <cfset l.Browser.Name = "Edge">
    <cfelseif FindNoCase ( "Chrome", l.UserInfo )>
        <cfset l.Browser.type = "Chrome">
        <cfset l.Browser.Name = "Chrome">
    <cfelseif FindNoCase ( "Safari", l.UserInfo )>
        <cfset l.Browser.type = "Safari">
        <cfset l.Browser.Name = "Safari">
    <cfelseif FindNoCase ( "FireFox", l.UserInfo )>
        <cfset l.Browser.type = "FireFox">
        <cfset l.Browser.Name = "FireFox">
    <cfelseif FindNoCase ( "MSIE", l.UserInfo ) >
        <cfset l.Browser.type = "MSIE">
        <cfset l.Browser.Name = "Internet Explorer">
    <cfelseif FindNoCase ( "Trident", l.UserInfo ) >
        <cfset l.Browser.type = "Trident">
        <cfset l.Browser.Name = "Internet Explorer">
    <cfelse>
        <cfset l.Browser.type = "Unknown">
        <cfset l.Browser.Name = "Unknown">
        <cfset l.Browser.Version = "Unknown">
    </cfif>

    <cfif FindNoCase ( "rv:" , l.UserInfo ) NEQ 0>
        <cfset l.Params = REFindNoCase ( "rv:[0-9.]+", l.UserInfo, Find ( "rv:", l.UserInfo ), true )>
        <cfset l.FirstOccurrence = l.Params.POS[1]>
        <cfset l.ParamLength = l.Params.LEN[1]>
        <cfset l.BrowserNameLength = Len ( "rv:" )>
        <cfset l.Browser.Version = Mid ( l.UserInfo, ( l.FirstOccurrence + l.BrowserNameLength ), ( l.ParamLength - l.BrowserNameLength ) )>
     <cfelse>
        <cfset l.Params = REFindNoCase ( #l.Browser.type# & "/?[ 0-9.]+", l.UserInfo, Find ( "#l.Browser.type#", l.UserInfo ), true )>
        <cfset l.FirstOccurrence = l.Params.POS[1]>
        <cfset l.ParamLength = l.Params.LEN[1]>
        <cfset l.BrowserNameLength = Len ( l.Browser.type ) + 1>
        <cfset l.Browser.Version = Mid ( l.UserInfo, ( l.FirstOccurrence + l.BrowserNameLength ), ( l.ParamLength - l.BrowserNameLength ) )>
     </cfif>

     <cfreturn l.Browser>
</cffunction>

<cfdump var="#GetBrowser()#">
SeriesBlue
  • 21
  • 4
0

There's nothing built into ColdFusion that will allow you to do this. Capturing the user_agent string and parsing it manually is about the best you can do.

There are third party apps like Browserhawk (http://www.cyscape.com/Default.aspx) that will do this... and while I've not used Browserhawk myself, I understand that it does the job well.

Googling also turns up http://www.andrewdixon.co.uk/aebrowser/, but that is 6 years old. Might still work... but depending on how bulletproof you need the solution to be, you might want to consider something like Browserhawk. You could google for a list of user agent strings and handle it yourself... but given the sheer number of browsers (and versions) across OS's, I think that'd be a full time job in and of itself.

charliegriefer
  • 3,342
  • 1
  • 18
  • 20