toggle menu

[JavaScript] UserAgent, 그리고 Switch 문의 정규식

2016. 2. 16. 18:37 JavaScript

들어가며


프로젝트를 진행하는 과정에서 PC 브라우저를 구분해줘야 할 필요가 생겼는데, Edge 브라우저까지 고려해서 정리해주면 좋겠다 싶어서 시간을 내서 각 브라우저별 UserAgent 를 리스팅하고 이를 바탕으로 브라우저 구별 스크립트를 짜봤다. 




브라우저별 UserAgent


주요 브라우저인 Edge, IE, Chrome, Safari, FireFox, Opera 의 UserAgent 패턴을 찾기위해 아래와 같이 한 두개씩 리스팅했다. 완벽하진 않겠지만 아래의 리스트를 바탕으로 패턴을 찾는다면 대부분의 케이스에서 브라우저를 구별할 수 있을 것이다.


Edge

Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136


IE11

Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko

Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko


IE10

Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 7.0; InfoPath.3; .NET CLR 3.1.40767; Trident/6.0; en-IN)

Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)


IE9

Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)

Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7)


IE8

Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.2; SV1; .NET CLR 3.3.69573; WOW64; en-US)

Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)


IE7

Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)

Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)


IE6

Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)

Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.1)

Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)


Chrome

Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36


Safari

Mozilla/5.0 (Windows; U; Windows NT 6.1; ko-KR) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4


파이어폭스

Mozilla/5.0 (Windows; U; Windows NT 6.1; ko; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 IPMS/A640400A-14D460801A1-000000426571

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:44.0) Gecko/20100101 Firefox/44.0


오페라

Opera/9.80 (Windows NT 6.1; U; ko) Presto/2.6.30 Version/10.62


위의 브라우저별 UserAgent 를 기준으로 할때, IE -> 엣지 -> 크롬 -> 사파리 -> 파이어폭스 -> 오페라 순으로 브라우저를 체크해주면 브라우저를 정확하게 구분해줄 수 있음을 알 수 있다. 사실 IE, 파이어폭스, 오페라는 순서에 관계없고 IE는 점유율을 생각해서 처음에 체크해주는 것이 유리할 것으로 판단했다. 


엣지가 크롬이나 사파리보다 먼저인 것은 엣지의 UserAgent 에는 Chrome 과 Safari 라는 문구가 모두 포함되어 있기 때문이다. 마찬가지로 크롬에도 Safari가 포함되어 있기 때문에 Safari 보다 앞에서 체크해야 한다. 또 IE 의 경우 11부터 MSIE 라는 문구가 빠지고 이전 버전의 경우 Trident 가 누락될 수 있기 때문에 이 두가지 케이스를 모두 체크해줄 필요가 있다.




Switch 문의 정규식


어쩌면 안티패턴일지도 모르겠지만, Switch문 안에 정규식으로 case 를 작성해서 브라우저를 구별하는 스크립트를 작성했다. if/else 로 하는것보다 성능상 나아지는 것도 떨어지는 것도 없지만 switch문에 정규식을 쓰는것은 뭔가 바람직하지 않은 느낌이 든다. (사실 switch문의 정규식때문에 이 포스팅을 작성하고 있다..)


var browserName = undefined;
var userAgent = navigator.userAgent;

switch (true) {
	case /Trident|MSIE/.test(userAgent):
		browserName = 'ie';
		break;

	case /Edge/.test(userAgent):
		browserName = 'edge';
		break;

	case /Chrome/.test(userAgent):
		browserName = 'chrome';
		break;

	case /Safari/.test(userAgent):
		browserName = 'safari';
		break;

	case /Firefox/.test(userAgent):
		browserName = 'firefox';
		break;

	case /Opera/.test(userAgent):
		browserName = 'opera';
		break;

	default:
		browserName = 'unknown';
}



Switch 문 안의 정규식.. 뭔가 나쁜 짓을 한 것 같은 기분이 들지만, 잘 동작하고 실제 성능상으로도 if/else 로 정규식 비교를 한 것과 차이가 없다. 성능상의 차이가 있을까 싶어 염려한 누군가가 jsperf 에 복잡한 케이스는 아니지만 간단한 switch 문과 정규식을 사용한 if/else , switch 문의 비교를 해놓았다.




https://jsperf.com/switch-vs-if-else-and-regex


단순 비교만 하는 switch 문이 가장 성능이 좋고 if/else 로 정규식을 비교하는 것과 switch 문에 정규식을 사용하는 것은 성능상 큰 차이가 없음을 알 수 있다. 물론 그렇다고 이렇게 switch 문 안에서 정규식을 사용하는 것을 장려하는 것은 아니다. 다만 이런 식으로도 사용 가능한 자바스크립트의 유연함에 재미있다는 생각이 들었다. (마무리하고 있는 지금.. 뭔가 약간 심심한 글이 되어 버린 기분이..)




참조

http://ohgyun.com/292/

http://www.useragentstring.com/

http://jsperf.com/switch-vs-if-else-and-regex/





JavaScript 관련 포스팅 더보기