게임을 그리다

[Javascript] geolocation으로 접속자의 위도, 경도 구하기 본문

[Javascript] geolocation으로 접속자의 위도, 경도 구하기

개발/Javascript 2016. 6. 17. 18:51

HTML5이 공개된지 어언 6년지 지났다. HTML5의 등장에 이어 새로이 소개된 기능중 하나로, .geolocation이 등장했다. 이는 브라우저가 접속한 유저의 정밀한 위도, 경도를 제공하는 Javascript API가 되는데 아이피를 기반으로한 ISP 업체 주소가 아니라, 정말 접속한 PC의 위도, 경도를 구해줄만큼 정밀하면서도 보안에 지대한 영향을 미칠것으로 예상된다. geolocation API는 navigator.geolocation 객체로서 제공되며, 프로그래머는 그냥 이 객체를 이용해서 접속자의 위치를 구하면 된다.


하지만 이 방법에는 큰 결함이 있는데, 다름아닌 보안이다. navigator.geolocation은 테스트 결과 파이어폭스, 인터넷 익스플로러까지는 정말로 잘 지원하지만.. 크롬에서는 https 프로토콜을 통한 보안 연결이 아닌경우 사용이 불가능하다. 쉽게말해 크롬 환경에서 navigator.geolocation은 프로토콜이 그냥 http가 아니라 https여야 Javascript 내부에서 접속자의 정밀한 위치를 제공받을 수 있다. 구글에서는 보안을 위한 정책이라고 말하고 있지만.. 나같은 소규모 개인 개발자 같은 경우 이게 큰 걸림돌이 된다. 필자는 이걸 어떻게든 고칠 방법을 찾았지만 엄두도 나지 않았고 https 인증서를 부여받는 비용이 너무 부담될 뿐이었다.


어떤 알고리즘을 사용하는지는 모르겠지만 필자가 얼핏 들은 내용으로는 구글의 위치 정보 API를 내부적으로 사용한다고 한다. 구글이 GPS도 없이 접속자의 위치를 예전부터 구해왔던건 변하지 않던 사실이다. 그리고 크롬에서 안되는 이유를 생각해볼때, 구글에 접속해보자. 구글은 HTTP가 아니라 HTTPS 프로토콜로 웹사이트를 제공한다. 그래서 크롬에서도 원활하게 위치 정보를 얻어올 수 있는 것. 위도, 경도를 이용해서 도시 정보등을 얻어오는 방법으로는 Google의 geolocation API 인 ‘Geocoding’ 이라는 API를 이용하면 된다. 이에 대해선 추후에 따로 포스팅할 예정.


자, 서론은 이만 접어두고 어떻게 geolocation API를 이용하는지 알아보자. geolocation API를 이용하기 전에 우선 브라우저가 geolocation API를 지원하는 Modern Browser인지 확인해야한다. 적어도 HTML5를 지원하지 않는 구식 브라우저는 대체적인 방법을 이용하도록 하는게 필자는 좋은 서비스 구축 방법이라고 생각한다. 우선 navigator 객체에 geolocation 멤버가 존재하는지를 체크하기 위해 'in' 연산자를 사용하여 사양을 우선 체크하면 된다:



// in 연산자를 쓰기 싫다면 그냥 navigator.geolocation을 사용해서 체크해도 된다.
if ("geolocation" in navigator) {
        // geolocation API를 브라우저가 지원한다면 실행할 코드
} else {
        // geolocation API를 브라우저가 지원하지 않는다면 실행할  코드
}


만약 브라우저가 geolocation API를 지원한다면 본격적으로 위치를 구할 차례이다. 복잡한 정의와는 달리 그저 함수 하나를 이용하면 되기 때문에 geolocation API는 상당히 이용하기 편하다. 위치를 구해오는 함수의 정의는 아래와 같다:



/**
 * 접속자의 현재 위치를 얻어옵니다.
 * @param onSuccessCallback 위치를 얻어오는데 성공할 경우 호출할 함수
 * @param onFailCallback 위치를 얻어오는데 실패할 경우 호출할 함수
 * @param positionOptions 위치를 얻어오는데 필요한 추가적인 설정 값
 */
navigator.geolocation.getCurrentPosition(onSuccessCallback, onFailCallback, positionOptions);


onSuccessCallback에 넘겨질 함수는 위치를 얻어오는데 성공했을시에 호출될 함수이며, 매개변수는 여러가지 위치 정보가 담긴 객체가 들어올 것이므로 매개변수 하나를 항상 열어놓자, 반대로 onFailCallback에 넘겨질 함수는 위치를 얻어오는데 실패할때 호출될 함수이다. 매개변수는 에러 정보가 담긴 객체가 들어올것이며 똑같이 매개변수 하나를 열어놓도록 하자. 여기서 가장 중요한건 positionOptions 매개변수인데, 이것은 geolocation API를 통해 위치를 얻어올때 개발자 입맛에 맞게 사양을 정할수 있다.


positionOptions 매개변수로 들어갈 객체의 멤버는 일단은 세가지로 볼수 있다.


enableHighAccuracy

정확도를 높이는지 여부에 대한 flag 값이다. 만일 이를 true로 설정하면 모바일 기기 같은 경우 '높은 정확도' 모드 처럼 배터리를 더 소모하는 부담이 있지만, 비교적 정확한 위치를 가져온다고 한다. 하지만 이를 false로 둘 경우 부하를 덜 주거나 요청 시간을 줄이는 등의 방법을 통해 비교적 부정확한 위치를 가져온다고 하니 참고해야한다. 


timeout

위치를 얻어오는데 timeout을 설정할수 있다. 단위는 밀리초(1ms = 1/1000초)이며, 기본값은 Infinity, 즉 응답이 돌아올때까지 계속 기다린다는 뜻이다. 페이지가 원활하게 동작할수 있도록 timeout을 걸어주는 것도 좋은 방법이라 할수 있겠다.


maximumAge

일단 단위는 밀리초 단위이다. 위치는 받아져오면 일단 캐시로써 남는다, 근데 이 멤버는 몇 밀리초 전까지의 캐시를 사용할 것인가를 의미한다. 0을 부여할 경우 캐시를 사용하지 않고 계속 현재 위치를 갱신하여 받아온다는 의미가 되고, 1000을 부여할 경우 1초 전 까지의 캐시된 위치 정보까지 받아오겠단 의미라고 할수 있겠다.


자, 이제 매개변수로 무엇을 요구하는지 알았으니 직접 코드를 작성해보자. 아래의 코드는 브라우저가 geolocation API를 지원하는지 확인한 뒤, 지원한다면 위치를 받아내어 콘솔에 로그하는 코드이다. 받아올 위치는 정확도가 높은 위치이며 timeout은 3초, 캐시는 사용하지 않는 정보를 얻어오도록 할것이다. 실패한다면, 에러 코드와 에러 정보를 내놓도록 한다.



function onGeolocationSuccess(position) {
		// 좌표 출력
		console.log("lat: " + position.coords.latitude + ", lon: " + position.coords.longitude); 
}

function onGeolocationFail(error) {
		// 에러 출력
		console.log("Error Code: " + error.code + ", Error Description: " + error.message);
}

if (navigator.geolocation) 
{
		// 정확한 위치 사용
		// 캐시 사용 안함
		// timeout 3초 (3000ms)
		var positionOptions = {
				enableHighAccuracy	: true, 
				maximumAge		: 0, 
				timeout			: 3000
		};

		navigator.geolocation.getCurrentPosition(onGeolocationSuccess, onGeolocationFail, positionOptions);
}


공유하기 링크
댓글 개