스터디/KAKAOCLOUDSCHOOL
[JavaScript] 개발자 지망생 스터디 - 10일차
shineIT
2022. 11. 15. 17:50
HTML5
■ Geo Location
- 개요
- 디바이스의 물리적 위치 정보를 파악하기 위한 Javascript API
- 위치 정보
- GPS와 같은 위성 정보를 이용해서 가져오는 방법
- 가까운 라우터의 위치
- 기지국의 위치 (가장 부정확함)
- GPS와 같은 위성 정보를 이용해서 가져오는 방법
- 위치 정보 사용을 허용 해야만 사용 가능
- 위치 정보 사용 가능 여부 확인
- navigator.geolocation 의 값을 확인
- 위치 정보를 가져와서 한 번만 사용하기
- navigator.geolocation.getCurrentPosition(위치 정보를 가져오는데 성공했을 때 호출되는 함수, 위치정보를 가져오는데 실패했을 때 호출되는 함수, 옵션)
- 위치정보를 가져오는데 성공했을 때 호출되는 함수에는 매개변수로 위치 정보롸 관련된 객체가 전달됨
- 이 객체가 저장하고 있는 정보는 JavaScript 뿐 아니라 모바일 API에서도 동일
- coords : latitude(위도), longitude(경도), altitude(고도-GPS가 아니면 없음), accuracy(정확도), altitudeAccuracy(고도의 정확성), heading(방향), speed(속도)
- timestamp : 위치 정보를 가져온 시간
- 위치정보를 가져오는데 실패했을 때 호출되는 함수에도 매개변수가 넘어가는데 이 경우에는 에러 객체가 전달되고 code 속성을 확인하면 실패의 이유를 알 수 있음
- 위치정보를 가져오는데 성공했을 때 호출되는 함수에는 매개변수로 위치 정보롸 관련된 객체가 전달됨
- navigator.geolocation.getCurrentPosition(위치 정보를 가져오는데 성공했을 때 호출되는 함수, 위치정보를 가져오는데 실패했을 때 호출되는 함수, 옵션)
- 위치 정보를 계속 가져와서 사용하기
- let 변수 navigator.geolocation.watchPosition(위치 정보를 가져오는데 성공했을 때 호출되는 함수, 위치 정보를 가져오는데 실패했을 때 호출되는 함수, 옵션)
- 위치 정보를 계속해서 파악하고 clearWatch(변수)를 호출하면 더 이상 위치 정보를 가져오지 않음.
- let 변수 navigator.geolocation.watchPosition(위치 정보를 가져오는데 성공했을 때 호출되는 함수, 위치 정보를 가져오는데 실패했을 때 호출되는 함수, 옵션)
- 옵션
- 객체 형태로 대입
- { enableHighAccuracy : 정확도가 높은 위치 정보를 사용하도록 하는 옵션. 기본값은 false
- timeout : 일정 시간이 지난 데이터는 폐기하는 옵션으로 밀리초 단위로 설정
- maximumAge } : 0을 설정하면 항상 최신의 데이터를 가져옴. 위치 정보를 가져오는 주기
- 스마트폰을 이용하는 경우 옵션 설정이 중요함.
- 스마트폰 배터리문제로 배터리를 가장 많이 소모하는 2가지 문제가 블루투스, GPS 를 이용하는 경우임.
- 객체 형태로 대입
- 웹 화면에 현재 위치에 해당하는 카카오 맵을 출력
- KAKAO Open API : https://developers.kakao.com/
- Key 발급
- 내 애플리케이션 ->애플리케이션 추가하기 -> key copy : -
- key는 바로 사용이 불가능 - 플랫폼 등록이 필요
- 네이티브 앱은 앱의 패키지 이름을 등록해야함
- 웹의 경우는 도메인을 등록해야함
- 연습할 때는 웹의 경우 http://localhost : 포트번호 형태로 등록하고 실제 서비스에 사용할 때는 localhost:포트번호 대신에 등록한 도메인이나 실 사용이 가능한 공인 IP 형태로 변경을 해야함
- 플랫폼 등록 - http://localhost:5500
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GeoLocation</title>
</head>
<body>
<div id="map" style="width:500px;height:400px;"></div>
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=--"></script>
<script>
var mapTypes = {
terrain : kakao.maps.MapTypeId.TERRAIN,
traffic : kakao.maps.MapTypeId.TRAFFIC,
bicycle : kakao.maps.MapTypeId.BICYCLE,
useDistrict : kakao.maps.MapTypeId.USE_DISTRICT
};
navigator.geolocation.getCurrentPosition((position) => {
var container = document.getElementById('map');
var options = {
center: new kakao.maps.LatLng(
position.coords.latitude, position.coords.longitude
),
level: 3
};
var map = new kakao.maps.Map(container, options);
map.addOverlayMapTypeId(mapTypes.traffic);
// 마커가 표시될 위치
var markerPosition = new kakao.maps.LatLng(
position.coords.latitude, position.coords.longitude);
// 마커 생성
var marker = new kakao.maps.Marker({
position: markerPosition
});
// 마커 지도 위에 표시
marker.setMap(map);
}, (error) => {
})
</script>
</body>
</html>
■ File API
- File을 읽고 쓰기 위한 API
- input type의 file에 miltiple 속성이 추가되서 이 속성의 값을 설정하면 여러 개의 파일을 선택하는 것이 가능
- 텍스트 파일을 읽을 때는 인코딩 설정에 주의해야 함
- 일반 파일을 읽을 때는 File Reader 객체를 생성한 후 reader.readAsDataURL(파일 객체)를 호출하고 load 이벤트와 error 이벤트를 처리 함
- load는 전부 읽었을 때 FileReader 객체의 result에 읽은 내용을 저장하고 error 이벤트는 읽기에 실패했을 때 실패한 이유를 저장하고 있는 객체를 넘겨줌
- 이미지 미리보기
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>이미지 미리보기</title>
</head>
<body>
<!-- 이미지 파일만 선택할 수 있는 file 객체 -->
<input type="file" accept="image/*" id="imginput"/>
<!-- 이미지 미리보기 영역 -->
<img id="display" width="250" height="250"/>
<script>
// 필요한 DOM 객체 찾아오기
let imginput = document.getElementById("imginput");
let display = document.getElementById("display");
// imginput 의 선택이 변경되면
imginput.addEventListener("change", (e) => {
// 선택한 파일의 내용을 읽기 - 비동기적 수행
let reader = new FileReader();
// 파일이 선택되었는지 확인
// JS에서는 0이 아닌 숫자, null, undefined 가 아니면 true로 간주 - turthy
if(!(imginput.files && imginput.files[0])){
alert("선택된 파일이 없음");
display.src = null;
return;
}
reader.readAsDataURL(imginput.files[0]);
// 파일의 내용을 다 읽으면 - callback
reader.addEventListener("load", () => {
// 읽은 내용을 이미지의 소스로 사용
display.src = reader.result;
})
});
</script>
</body>
</html>
■ Drag & Drop API
- 브라우저 내에서 사용할 수 있고 외부 프로그램과 브라우저 사이에서도 사용할 수 있음
- 외부 프로그램과 사용할 때는 외부 프로그램에서 드래그를 하고 브라우저에 드랍을 해야 함
- 파일을 첨부할 때 많이 사용함
■ 브라우저에 데이터를 저장
- 브라우저에 데이터를 저장하는 이유
- 불필요한 트래픽을 줄이기 위해서
- 메일 앱의 경우 매번 서버에 접속해서 서버의 데이터를 받아오는 것은 자원의 낭비가 될 수 있음.
- 맨 처음 접속을 할 때는 데이터를 다운로드 받고 (파일의 존재 여부 확인)
- 다음 부터는 마지막 업데이트된 시간을 비교해서 양쪽의 시간이 다르면 데이터가 수정된 것으로 간주하여 다운로드를 받고 양쪽의 시간이 같다면 업데이트된 내용이 없으므로 다운로드를 받지 않도록 구현함
- 서버를 업데이트할 때는 마자막 업데이트 날짜 시간을 기록하는 것이 중요함
- 오프라인 상태에서도 데이터를 사용하기 위해서
- local에 데이터 저장
- 불필요한 트래픽을 줄이기 위해서
- 브라우저에 데이터를 저장하는 방법
- Web Storage : Map의 형태로 저장
- Web SQL : 관계형 데이터베이스(SQLite3 - 외부에서는 접속이 불가능한 저용량 데이터베이스, 사용법은 MySQL과 유사) 이용
- Indexed DB : 자바스크립트 객체 형태로 저장 - NoSQL과 유사
- 기존에는 쿠키를 사용했는데 Cookie를 사용하게 되면 문자열만 저장할 수 있고, 서버에 매번 전송됨.전송 여부를 클라이언트가 결정할 수 없다,
- Web Storage
- 종류
- LocalStorage : 브라우저에 저장해서 지우지 않는 한 절대 삭제가 되지 않는 저장소
- SesstionStorage : 현재 접속 중인 브라우저에 해당하는 저장소로 접속이 종료되면 소멸
- 데이터 저장과 가져오기 그리고 삭제
- 저장 : 스토리지.키이름 = 데이터, 스토리지.["키이름"] = 데이터, 스토리지.setitem("키이름",데이터)
- 가져오기 : 스토리지.키이름, 스토리지.["키이름"], 스토리지.getitem("키이름")
- 삭제 : delet 스토리지.키이름, delet 스토리지.["키이름"], 스토리지.removeitem("키이름")
- 저장소에 데이터가 변경되면 window 객체에 storage 이벤트가 발생하고 이벤트 객체에는 key, oldValue, newValue, url, storageArea 같은 속성이 만들어 짐
- Local Storage는 전역 변수 localStorage로 사용할 수 있고 Session Storage는 sessionStorage로 사용할 수 있음
- 저장된 내용을 확인하는 방법은 브라우저의 검사 창에서 application을 확인하면 됨
- 세션 스토리지 - 브라우저를 종료했을 때 내용이 소멸되는지 와 현재 창에서 새창을 출력했을 때 내용이 복제가 되는지 확인
- 로컬 스토리지 - id 저장을 구현하는데 브라우저를 종료하고 다시 연결했을 때 내용이 존재하는지 여부를 확인
- 종류
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>세션 스토리지</title>
</head>
<body>
<!-- 2개의 문자열 입력받는 도구와 버튼 3개 -->
key<input type="text" id="keyinput"/>
value<input type="text" id="valueinput"/>
<input type="button" value="삽입" id="insertbtn"/>
<button id="removebtn">삭제</button>
<button id="addwindowbtn">윈도우 추가</button>
<!-- 데이터 출력 영역 -->
<fieldset>
<legend>데이터 출력 영역</legend>
<select id="list" size="10"></select>
</fieldset>
<script>
let keyinput = document.getElementById("keyinput");
let valueinput = document.getElementById("valueinput");
let insertbtn = document.getElementById("insertbtn");
let removebtn = document.getElementById("removebtn");
let addawindowbtn = document.getElementById("addwindowbtn");
let list = document.getElementById("list");
// 세션 스토리지의 내용을 읽어서 list에 출력하는 함수
// 처음 접속할 때 그리고 삽입이나 삭제를 할 때
// 매번 데이터를 다시 출력할 생각으로 코드를 여러번 작성을 하지 않기 위함임.
const showData = () => {
// list의 내용 초기화
list.innerHTML="";
// sessionStorage 순회 하나씩 읽기
for(let i=0; i<sessionStorage.length; i++){
let temp = sessionStorage.key(i);
// select 에 옵션을 추가
list.options[list.options.length] = new Option(temp + ":" + sessionStorage[temp], temp);
}
}
// 윈도우가 모든 데이터를 로드 한 후
window.addEventListener("load", () => {
// Live Server를 이용해서 실행하면 기본적으로 하나의 데이터가 저장되서 출력됨
showData();
})
// Insert 삽입 버튼을 눌렀을 떄
insertbtn.addEventListener("click", () => {
// 세션 스토리지에 저장
sessionStorage[keyinput.value] = valueinput.value;
// 데이터를 다시 출력
showData();
})
// list를 클릭했을 때 클릭한 데이터를 input에 출력
list.addEventListener("click", () => {
// 선택한 데이터 찾아오기
let selecteddata = list.options[list.selectedIndex];
keyinput.value = selecteddata.value;
valueinput.value = sessionStorage[selecteddata.value];
})
// 삭제 버튼을 눌렀을 때 선택된 데이터 삭제
removebtn.addEventListener("click", () => {
delete sessionStorage[keyinput.value];
showData();
});
// 윈도우 추가 버튼을 눌렀을 때 새창으로 열기
addwindowbtn.addEventListener("click", () => {
// 새창에서 열면 세션은 현재 내용을 복제해서 생성
window.open(location.href);
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>local Storage ID 저장</title>
</head>
<body>
<form method="post" action="login" id="loginform">
ID<input type="text" id="id"/><br/>
PW<input type="password" id="pw"/><br/>
<input type="checkbox" id="idsave"/>아이디 기억하기<br/>
<input type="submit" value="로그인"/>
</form>
<script>
let loginform = document.getElementById("loginform");
let userid = document.getElementById("id");
let userpw = document.getElementById("pw");
let idsave = document.getElementById("idsave");
// form의 데이터를 전송 (submit)
loginform.addEventListener("submit", () => {
// check 여부 확인
if(idsave.checked === true){
// 로컬 스토리지에 저장
localStorage.saveid = userid.value;
}else{
// 로컬 스토리지에서 삭제
delete localStorage.saveid;
}
});
// 메모리 로드가 끝나면 userid 저장되어 있으면 가져오기
window.addEventListener("load", () => {
if(typeof localStorage.userid != 'undefined'){
userid.value = localStorage.saveid;
idsave.checked = true;
}
})
</script>
</body>
</html>
- 로컬 스토리지는 보안이 중요하지 않은 많지 않은 양의 데이터를 저장하는데 용이
- 장바구니 구현이나 저장에 유용하게 사용 가능
- 동일한 패턴의 데이터가 많은 경우, 로컬 스토리지 보다는 Web SQL 이나 Indexed DB를 권장
■ Web Worker
- Javascript를 이용한 백그라운드 처리
- Javascript에서는 Thread 표현 대신에 Worker 라는 표현을 사용
- HTML 과 함께 있는 Javascript 코드에서 긴 작업을 수행하게 되면 작업이 끝날때까지 다른 작업을 수행할 수 없음(UI는 아무것도 할 수 없는 상태)
- Web Worker는 UI 변경을 하지 못하고 DOM 객체 제어를 할 수 없지만 localStorage와 XMLHttpRequest(ajax) 사용은 가능
- Wev Worker 생성
- let 변수 = new Worker("자바스크립트 파일 경로"); // 워커는 별도의 스크립트 파일에 만들어야함
- 워커와 브라우저 사이의 메시지 전송
- 워커변수.postMessage("메시지") => 워커에서는 message 이벤트가 발생함
- 워커 file 에서는 postMessage("메시지") => 워커 변수에 message가 발생함
- sendMessage는 바로 처리해달라는 요청이고 postMessage는 다른 작업이 없으면 처리해달라고 하는 요청임
- message 이벤트가 발생하면 매개변수에 data 와 error를 가진 객체가 전달됩니다
- data는 data이고 error는 에러가 발생했을 때 에러에 대한 정보를 가진 객체임
- 워커는 terminate()를 호출해서 중지가 가능
1. 계산 작업을 대신 수행해주는 워커 생성 - worker.js
// html에서 요청이 오면
onmessage = (event) => {
// html에서 전송한 데이터 받기
let num = event.data;
// 1부터 num까지 합계 구하기
let result = 0;
for(let i=0; i<=num; i++){
result += i;
}
// html 파일로 결과를 전송
postMessage(result);
}
2. 워커를 호출하는 코드 작성 - html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>웹 워커</title>
</head>
<body>
<h1>Web Worker</h1>
숫자 입력<input type="number" id="num"/>
<button id="start">합계 구하기</button>
<script>
let num = document.getElementById("num");
let start = document.getElementById("start");
let worker;
start.addEventListener("click", () => {
// 워커가 만들어져 있으면 중지
if(worker){
worker.terminate();
}
// 워커 생성
worker = new Worker("worker.js");
// 메시지 전송
worker.postMessage(Number(num.value));
// 워커가 결과를 전송했을 때
worker.onmessage = (event) => {
// 워커가 전송한 데이터 출력
alert(event.data);
}
});
</script>
</body>
</html>
■ Application Cache
- 리소스의 일부분을 로컬에 저장하기 위한 기능
- 오프라인 브라우징이 가능해지고 리소스를 빠르게 로드 할 수 있고 서버 부하를 감소시킬 수 있음.
- css나 js 그리고 이미지 파일 등을 캐싱
■ Web Push
- Server Sent Events : 클라이언트의 요청 없이 서버가 클라이언트에게 메시지를 전송하는 것
- 사용 이유 : 알림
- Apple Server가 보내는 Push를 APNS(Apple Push Notification Service)
- Google Server가 보내는 Push를 FCM(Firebase Cloud Message)라고 함.
■ Web Socket
- Web에서의 TCP 통신을 위한 API
- 일반적인 Web 요청의 처리 방식은 Client가 Server에게 접속을 한 후 하나의 request 를 전송하고 그 request를 Server가 받으면 처리를 하고 response 를 Client에게 전송하고 접속이 끊김
- 연속되는 작업을 처리하기 위해서 Cookie(클라이언트의 브라우저에 저장) 와 Session(서버에 저장) 이라는 개념을 도입
- 일반적인 Web 요청(HTTP 나 HTTPS)은 본문 이외에 헤더 정보를 같이 전송해야 함.
- 작은 사이즈의 데이터를 보내는 경우 오버헤드가 너무 큼
- Web Socket을 이용하면 헤더가 거의 없기 때문에 이러한 오버헤드를 줄일 수 있음
- 작은 양의 메시지를 자주 주고 받는 경우는 ajax 나 Fetch API 보다는 Web Socket을 사용하는 것을 권장
Node.js
1. 개요
- 애플리케이션을 개발할 수 있는 자바스크립트 환경
- 원래 자바스크립트는 브라우저 내에서 동적인 작업을 처리하기 위한 언어
- 실제 내부 코드는 C++로 되어 있음
- 장점
- 자바스크립트 엔진을 사용하기 때문에 접근이 쉬움 - Learning Curve가 짧다
- 비동기 방식으로 리소스 사용량이 적음
- 다양한 라이브러리 제공
- 단점
- Native 언어로 만든 서버 환경보다는 느릴 수 있음.
- 짧은 시간에 대량의 클라이언트 요청을 대응하는 웹 애플리케이션 개발에 적합하고 대량의 데이터를 조회하고 긴 처리 시간을 요구하는 작업에는 부적합
- 이러한 단점의 대용량 연산 작업을 할 때는 직접 구현하지 않고 AWS의 Lambda나 Google Cloud Functions 같은 서비스를 이용하여 어느정도 해결 가능함
- 웹 서버 이외의 노드
- SPA(Single Page Application) : Angular, React, Vue 등
- 모바일 앱 프레임워크 : React Native
- 데스크 탑 애플리케이션 : Eeletron(Atom, slack, VSCode, 블록체인 애플리케이션 등)
- 외부 라이브러리 활용
- npm 이라는 프로그램을 이용
- npm을 이용하면 기능을 확장한 수많은 모듈을 쉽게 다운로드 하고 설치할 수 있음
- 최근에는 npm 대신 yarn을 사용하는 경우도 많음
- 장점
2. Node 설치
- 버전
- LTS : 안정화된 버전으로 짝수
- Current : 현재 개발중인 버전
- 설치
- Windows 는 https://nodejs.org에서 다운로드 받아서 설치
- Mac은 다운로드 받아서 설치해도 되고 터미널 brew install node 로 설치 가능
- 설치 확인
- 터미널
- node -v : 노드 버전 확인
- npm -v : npm 버전 확인
- 터미널
- IDE 설치
- VSCode 사용
3. Node 프로젝트 만들기
- 빈 디렉토리에서 npm init 이라는 명령어로 생성하고 옵션을 설정
- 옵션 설정
- pakage name : pakage를 배포할 때 사용할 이름이며 디렉토리 이름과 같으면 안됨.
- version : 버전 (나온 버전 그대로 엔터를 쳐도 무방함)
- description : 앱에 대한 설명
- entry point : 시작하는 파일 이름 (앱의 출발점으로 index.js or App.js를 많이 사용
- test command : 앱을 테스트할 때 사용할 명령어 이름
- git repository : git 과 연동할 때 사용할 URL
- keywords : 패키지가 배포된 경우 사용할 검색어
- author : 제작자
- license : ISC 나 MIT를 사용하는데 오픈 소스라는 의미
- 생성에 성공하면 pakage.json이 생성
- 프로젝트 실행
- npm start 하게 되면 entry point로 지정한 파일이 실행
- node 파일명 을 하게 되면 파일이 실행
- cd 는 디렉토리를 변경하는 명령어
- cd 디렉토리 이름을 입력하면 디렉토리로 프롬프트를 이동
- cd .. 을 입력하면 상위 디렉토리로 이동