Detecting browsers javascript hacks
Thursday, 29 January 2009
I enjoyed my last experiment to create tiny browser detection hacks, so I thought I’d try and do some more in other browsers. I’ve found these while testing Hackvertor and writing the inspection functions. The rules are simple if you want to post your own:-
1. The variable assignment must be the abbreviation of the browser. E.g. FF, IE, Op, Saf, Chr.
2. The detection shouldn’t be able to be overwritten. E.g. IE=!!top.execScript is incorrect because a web site can redefine execScript as a variable or function.
3. Small and as fast as possible please.
To start off, this one was found by DoctorDan from the slackers forums:-
//Firefox detector 2/3 by DoctorDan
FF=/a/[-1]=='a'
//Firefox 3 by me:-
FF3=(function x(){})[-5]=='x'
//Firefox 2 by me:-
FF2=(function x(){})[-6]=='x'
//IE detector I posted previously
IE='\v'=='v'
//Safari detector by me
Saf=/a/.__proto__=='//'
//Chrome by me
Chr=/source/.test((/a/.toString+''))
//Opera by me
Op=/^function \(/.test([].sort)
//IE6 detector using conditionals
try {IE6=@cc_on @_jscript_version <= 5.7&&@_jscript_build<10000} catch(e){IE6=false;}
As I come across more developing Hackvertor I shall post them here. Please post your own or verify any of the ones posted.
Update...
One line to rule them all:-
B=(function x(){})[-5]=='x'?'FF3':(function x(){})[-6]=='x'?'FF2':/a/[-1]=='a'?'FF':'\v'=='v'?'IE':/a/.__proto__=='//'?'Saf':/s/.test(/a/.toString)?'Chr':/^function \(/.test([].sort)?'Op':'Unknown'
No. 1 — January 29th, 2009 at 10:01 am
Nice!
No. 2 — January 29th, 2009 at 11:26 am
That is pretty epic I wont lie. *Blogs this*
No. 3 — January 29th, 2009 at 11:52 am
I can make it smaller if you’re not interested in which version of FF:-
B=/a/[-1]==’a’?’FF’:’\v’==’v’?’IE’:/a/.__proto__==’//’?’Saf’:/s/.test(/a/.toString)?’Chr’:’Op’
//94!
No. 4 — January 29th, 2009 at 2:07 pm
This is pretty insane, man!
I sure do hope it gets implemented in jQuery’s and the other libraries’ cores…
No. 5 — January 29th, 2009 at 2:36 pm
It gives ‘Op’ in FF3.1 beta2.
No. 6 — January 29th, 2009 at 2:47 pm
@Sam
I’ve updated the one rule, please try again. If you can please run this hackvertor code to see what results in FF3.1 beta :-
http://www.businessinfo.co.uk/labs/hackvertor/hackvertor.php?input=Ly9DbGljayAiaW5zcGVjdCBvdXRwdXQiCmFsZXJ0
No. 7 — January 30th, 2009 at 9:08 am
Another little change would be a CSS-Selector in 252 Bytes:
document.getElementsByTagName(‘html’)[0].className+=’ ‘+(function x(){})[-5]==’x’?’FF3′:(function x(){})[-6]==’x’?’FF2′:/a/[-1]==’a’?’FF’:’\v’==’v’?’IE’:/a/.__proto__==’//’?’Saf’:/s/.test(/a/.toString)?’Chr’:/^function \(/.test([].sort)?’Op’:’Unknown’
You can use:
.IE .example { color: red; }
.FF2 . example { color: lime; }
etc…
(classNames are case sensitive!)
Have fun 🙂
No. 8 — January 30th, 2009 at 10:03 am
One obvious point is that browser detection is something that should be avoided wherever possible – feature detection should be used instead otherwise your website won’t work on the next browser released…
No. 9 — January 31st, 2009 at 3:31 am
Opera test doesn’t quite satisfy your rules, as it can be easily overwritten:
Array.prototype.sort.toString = function(){ return ‘function (){}’ }
/^function \(/.test([].sort); // true
No. 10 — January 31st, 2009 at 3:35 am
Safari check can be fooled in the very same way, of course:
RegExp.prototype.toString = function(){ return ‘//’ };
/a/.__proto__==’//’; // true
No. 11 — February 4th, 2009 at 6:45 pm
These are most excellent. I just used a few in a bookmarklet for adding new css rules to the page
The safari test only catches safari proper and not the webkit-also Chrome… Do you have a clever solution to catch both? (I recognize they’re different js engines, but come on.. you’re clever. 🙂
No. 12 — February 4th, 2009 at 10:33 pm
@Paul
I’ve not got Chrome handy at the moment because I’m on a different computer. However this should work:-
WebKit=typeof document.body.style.WebkitAppearance==’string’;
This can be overwritten though so technically it breaks the rules but it might be good enough for what you want.
No. 13 — February 5th, 2009 at 2:06 pm
Just to confirm it does work in Chrome and Safari 😀
No. 14 — February 6th, 2009 at 6:35 pm
Gareth, you are a machine. Well done.
No. 15 — March 16th, 2009 at 1:06 pm
Nice stuff!
No. 16 — April 8th, 2009 at 10:53 pm
The Opera test does not work in 9.2x
No. 17 — April 24th, 2009 at 8:51 pm
IE=@cc_on true ? true : @false;
Internet Explorer supports <a href=”http://msdn.microsoft.com/en-us/library/ahx1z4fs(VS.80).aspx”>conditional compilation</a> which can be used to accurately detect its version:
IE8=@cc_on @_jscript_version == 5.8 ? true : @false
IE7=@cc_on @_jscript_version == 5.7 ? true : @false
IE6=@cc_on @_jscript_version == 5.6 ? true : @false
IE55=@cc_on @_jscript_version == 5.5 ? true : @false
No. 18 — April 24th, 2009 at 8:53 pm
My asterisks and slashes have vanished.
There should be a block comment opened right before each @cc_on, and closed after the final @.
No. 19 — April 25th, 2009 at 6:44 am
@Gyrobo
Sorry about that I remove comments from WordPress to avoid SQL injection attacks.
Conditional comments work well but not when the code is compressed
No. 20 — April 25th, 2009 at 1:12 pm
Quite a great effect.
Thanks for sharing.
No. 21 — April 28th, 2009 at 12:37 pm
Well then, I guess I learned something about both compression and SQL injection. Yay!
No. 22 — June 25th, 2009 at 12:38 pm
Ð¥Ð¾Ñ€Ð¾ÑˆÐ°Ñ ÑтатьÑ, больше бы таких!
No. 23 — July 31st, 2009 at 11:17 am
Рподробнее можно?
No. 24 — July 31st, 2009 at 11:51 am
Да, больше невозможно. Попробуйте JavaScript Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ CSS ÑвойÑтва как МОЗ или MS-Ñ‚.д.
No. 25 — August 4th, 2009 at 4:33 pm
hello,
great stuff! it seems that the one line detector is just returning ‘FF’ for firefox 3.5.1 mac+win. Any chance of a fix?
best,
-D
No. 26 — August 4th, 2009 at 5:01 pm
@d
This should detect FF3.5 and above:-
FF3=(/a/[-1]&&Object.getPrototypeOf)?true:false
No. 27 — December 1st, 2009 at 3:47 pm
Just wanted to share two hacks I’m currently using (in LABjs) for detecting Firefox(Gecko) and for detecting Opera:
is_opera = window.opera && Object.toString.call(window.opera) == “[object Opera]”
is_gecko = (function(o) { o[o] = o+””; return o[o] != o+””; })(new String(“__count__”))
No. 28 — December 1st, 2009 at 7:22 pm
@gareth:
thanks brother!
No. 29 — December 17th, 2009 at 12:14 pm
The IE check can be shortened to:
No. 30 — December 17th, 2009 at 12:28 pm
@Mathias
Yeah someone already pointed that out:-
http://sla.ckers.org/forum/read.php?2,15812,26331,page=13#msg-26331
No. 31 — December 18th, 2009 at 1:32 pm
I didn’t know that. thank you
No. 32 — December 23rd, 2009 at 1:36 am
When I run the one-liner in Mac Google Chrome, I get “Unknown”.
Any chance someone could update the one-liner to work with Mac Google Chrome?
No. 33 — February 9th, 2010 at 2:10 pm
/a/[-1]==’a’ isn’t work on firefox3.6
No. 34 — February 9th, 2010 at 2:13 pm
@superhei
Yep Mozilla decided this was a security issue when I reported it so these techniques can no longer be expected to work in later versions of Firefox
No. 35 — February 18th, 2010 at 5:53 pm
i was wondering why are you using ((/a/.toString+”)) instead of (/a/.toString+”) ?
No. 36 — February 18th, 2010 at 10:09 pm
@noob
Yeah probably a typo nobody is perfect 🙂
No. 37 — March 19th, 2010 at 6:06 pm
Yeah probably a typo nobody is perfect
No. 38 — April 19th, 2010 at 6:16 pm
FireFox keeps being detected as Chrome
function getBrowser()
{
if( _browser == undefined )
{
_browser = (function x(){})[-5]==’x’
?’FF3′:/a/[-1]&&Object.getPrototypeOf
?’FF2′:/a/[-1]==’a’
?’FF’:’\v’==’v’
?’IE’:/a/.__proto__==’//’
?’SAF’:(/a/.toString+”)
?’CHR’:/^function \(/.test([].sort)
?’OP’:’Unknown’;
/* not sure what’s wrong w/ the above oneliner.. */
if( /a/[-1]&&Object.getPrototypeOf ) _browser = ‘FF3’;
if( _browser == ‘IE’ && isIE8() ) _browser = ‘IE8’;
if( _browser == ‘IE’ && isIE7() ) _browser = ‘IE7’;
if( _browser == ‘IE’ && isIE6() ) _browser = ‘IE6’;
}
return USE_LOWERCASE_BROWSER ? _browser.toLowerCase() : _browser;
}
No. 39 — April 29th, 2010 at 12:53 pm
Hi,
Nice trick for detecting browsers. I am adding this to my blog.
No. 40 — August 15th, 2010 at 8:41 pm
Nice artcile)
Translated & posted.
No. 41 — September 8th, 2010 at 8:55 am
This is sweet! I use ie and Fire Fox depending on what I’m doing or where I’m browsing. This will be great to keep peoples noses out of my browser!