방송대 HTML5웹프로그래밍 15강: 웹 스토리지와 위치 정보 API
브라우저에 값을 저장했다고 해서 언제까지 남고 어느 탭에서 보이는지가 자동으로 결정되는 것은 아닙니다. 위치 요청도 좌표 하나를 받는 호출이 아니라 권한·성공·실패·중지 상태를 관리하는 과정입니다. 이 글은 학습 도우미 앱의 상태 전이를 따라 localStorage와 sessionStorage의 수명, 탭 간 동기화, 안전한 JSON 복구, 단발 위치 요청과 연속 추적을 판단하는 방법을 설명합니다.
두 API는 모두 상태의 소유자와 종료 조건을 묻는다
학습 도우미 앱에 세 기능이 있다고 가정해 봅시다. 테마 설정은 브라우저를 닫았다 열어도 남아야 하고, 시험 답안 초안은 현재 탭의 작업이 끝나면 사라져도 됩니다. 가까운 학습 장소 찾기는 버튼을 누른 순간 한 번만 위치가 필요하지만, 산책 학습 기록은 사용자가 멈출 때까지 위치 갱신을 구독해야 합니다.
| 기능 | 소유 범위 | 종료 조건 | 후보 API |
|---|---|---|---|
| 테마 설정 | 같은 출처의 지속 상태 | 삭제·사용자 정책·브라우저 정리 | localStorage |
| 한 탭의 답안 초안 | 출처와 탭의 세션 | 해당 페이지 세션 종료 | sessionStorage |
| 현재 장소 한 번 확인 | 사용자가 허용한 위치 요청 | 성공 또는 실패 콜백 | getCurrentPosition() |
| 이동 경로 기록 | 사용자가 허용한 위치 구독 | clearWatch() 호출 | watchPosition() |
웹 스토리지는 “어디에 얼마나 오래 기억할지”를 정하고, Geolocation API는 “언제 위치를 요청하고 언제 구독을 끝낼지”를 정합니다. 두 기능 모두 편리함만 보고 고르면 과도한 보존이나 불필요한 추적이 생깁니다. 데이터의 민감도, 필요한 수명, 공유 범위와 명시적 종료를 먼저 정한 뒤 API를 선택해야 합니다.
첫 질문: 이 데이터는 누가 볼 수 있어야 하고, 언제 없어져야 하며, 사용자가 거부하거나 기능을 끝냈을 때 어떤 상태로 돌아가야 하는가?
웹 스토리지는 문자열 키와 문자열 값의 저장소다
Web Storage는 클라이언트의 저장 영역에 이름과 값의 쌍을 보관하는 API입니다. 쿠키와 달리 HTTP 요청 헤더에 자동으로 붙어 서버로 전송되지 않습니다. 그렇다고 서버가 절대 볼 수 없다는 뜻은 아닙니다. 애플리케이션 코드가 값을 읽어 네트워크 요청에 넣으면 전송될 수 있으므로 보안 판단은 자동 전송 여부만으로 끝나지 않습니다.
Storage 인터페이스는 setItem(), getItem(), removeItem(), clear(), key(), length를 제공합니다. 키가 이미 있으면 setItem()이 값을 교체하고, 없는 키를 getItem()으로 읽으면 null을 돌려줍니다.
localStorage.setItem("theme", "dark");
const theme = localStorage.getItem("theme");
if (theme === null) {
console.log("저장된 테마가 없습니다.");
} else {
console.log(`현재 테마: ${theme}`);
}
localStorage.removeItem("theme");
키와 값은 문자열로 다뤄집니다. 숫자 7을 넣어도 읽을 때는 "7"이므로 계산 전에 변환해야 합니다. 점 표기나 대괄호 표기도 가능하지만 length, clear 같은 기존 이름과 충돌할 수 있어 저장 의도가 분명한 메서드 사용이 안전합니다.
local과 session은 수명보다 공유 경계에서 먼저 갈린다
localStorage는 같은 출처의 여러 문서가 공유하는 지속 저장 영역입니다. 브라우저를 닫았다고 곧바로 사라지지는 않지만 “영구 보존”을 보장하는 데이터베이스로 이해하면 안 됩니다. 사용자가 사이트 데이터를 지우거나 브라우저 정책이 정리할 수 있고, 저장 접근 자체가 제한될 수도 있습니다.
sessionStorage는 출처뿐 아니라 최상위 탐색 문맥, 즉 보통 탭 단위의 페이지 세션에 묶입니다. 같은 출처를 새 탭에서 열면 일반적으로 독립된 저장 영역을 사용합니다. 한 탭 안의 같은 출처 iframe은 같은 세션 영역을 공유할 수 있으므로 단순히 “한 문서 전용”이라고 부르는 것도 정확하지 않습니다.
| 판정 질문 | localStorage | sessionStorage |
|---|---|---|
| 새로 열어도 설정을 이어 써야 하는가? | 적합한 후보 | 페이지 세션 종료 뒤 기대하지 않음 |
| 다른 탭과 값을 공유해야 하는가? | 같은 저장 영역을 공유 가능 | 별도 탭은 보통 분리 |
| 한 작업 흐름에만 필요한가? | 수명이 불필요하게 길 수 있음 | 다단계 폼의 임시 상태에 적합 |
| 자동 만료 시각이 필요한가? | 둘 다 만료 로직을 애플리케이션에서 설계 | |
테마·글꼴 크기처럼 민감하지 않은 선호는 localStorage, 한 탭에서만 진행하는 퀴즈 단계는 sessionStorage가 자연스럽습니다. 비밀번호, 결제정보, 세션 인증 토큰처럼 탈취 피해가 큰 값은 Web Storage에 두지 않습니다. Web Storage에는 쿠키의 HttpOnly처럼 자바스크립트 접근을 차단하는 속성이 없기 때문입니다.
객체 저장은 직렬화와 검증을 하나의 왕복으로 묶는다
객체를 setItem()에 그대로 넘기면 의미 있는 구조가 보존되지 않고 문자열로 변환됩니다. 저장 전에는 JSON.stringify(), 읽은 뒤에는 JSON.parse()를 사용합니다. 하지만 키가 없거나 저장된 문자열이 손상되었을 때까지 고려해야 안전한 왕복이 됩니다.
const SETTINGS_KEY = "study-settings";
function saveSettings(settings) {
const payload = JSON.stringify(settings);
localStorage.setItem(SETTINGS_KEY, payload);
}
function loadSettings() {
const payload = localStorage.getItem(SETTINGS_KEY);
if (payload === null) return { theme: "light", fontSize: 16 };
try {
const parsed = JSON.parse(payload);
if (typeof parsed.theme !== "string") throw new Error("invalid theme");
if (!Number.isFinite(parsed.fontSize)) throw new Error("invalid fontSize");
return parsed;
} catch (error) {
localStorage.removeItem(SETTINGS_KEY);
return { theme: "light", fontSize: 16 };
}
}
직렬화가 성공했다고 데이터의 의미까지 올바른 것은 아닙니다. 읽은 객체의 필드를 검증하고, 이전 버전 형식이나 손상 데이터라면 기본값으로 복구합니다. 함수·undefined·순환 참조 등은 JSON 왕복에서 그대로 보존되지 않으므로 저장 모델을 단순한 데이터 구조로 설계해야 합니다.
상태 전이: 키 없음 → 기본값, 정상 문자열 → 파싱·검증된 객체, 손상 문자열 → 삭제 후 기본값으로 이동합니다. “읽기 성공”과 “사용 가능한 데이터”는 같은 상태가 아닙니다.
저장은 성공·용량 초과·접근 거부로 갈라질 수 있다
웹 스토리지 용량은 브라우저와 정책에 따라 달라지므로 “항상 5MB”처럼 고정값으로 설계하지 않습니다. 할당량을 넘거나 사이트의 저장이 차단되면 setItem()이 QuotaExceededError를 던질 수 있습니다. localStorage 속성에 접근하는 단계도 출처나 사용자 정책에 따라 SecurityError가 날 수 있습니다.
function trySaveLocal(key, value) {
try {
const storage = window.localStorage;
storage.setItem(key, value);
return { ok: true };
} catch (error) {
if (error instanceof DOMException && error.name === "QuotaExceededError") {
return { ok: false, reason: "quota" };
}
return { ok: false, reason: "unavailable" };
}
}
const result = trySaveLocal(
SETTINGS_KEY,
JSON.stringify({ theme: "dark", fontSize: 18 })
);
if (!result.ok) {
console.warn("설정을 브라우저에 저장하지 못했습니다.", result.reason);
}
단순 지원 여부를 typeof window.localStorage로만 확인하면 실제 쓰기 가능성을 알 수 없습니다. 작은 시험 값을 쓰고 지우는 방법도 있지만, 이 작업 자체가 실패할 수 있으므로 예외 처리 안에 넣어야 합니다. 이미지나 큰 JSON처럼 무거운 데이터를 동기식 Web Storage에 쌓기보다 큰 구조화 데이터에는 IndexedDB 같은 목적에 맞는 저장소를 검토합니다.
clear()는 해당 저장 영역의 모든 키를 지웁니다. 한 기능의 초기화 버튼이라면 서비스의 다른 기능이 저장한 값까지 없애지 않도록 소유한 키만 removeItem()으로 삭제하는 편이 안전합니다.
목록 렌더링은 키 순서와 문자열 신뢰를 가정하지 않는다
length와 key(index)로 저장된 항목을 순회할 수 있지만 키의 반복 순서는 구현이 정하며 변경 뒤 달라질 수 있습니다. 순서가 중요한 목록이라면 별도의 정렬 기준을 저장하거나 읽은 뒤 정렬합니다. 또한 키와 값은 외부 입력처럼 취급해 innerHTML 문자열에 직접 끼우지 않습니다.
function renderStorage(storage, tableBody) {
const entries = [];
for (let index = 0; index < storage.length; index += 1) {
const key = storage.key(index);
if (key === null) continue;
entries.push([key, storage.getItem(key) ?? ""]);
}
entries.sort(([keyA], [keyB]) => keyA.localeCompare(keyB, "ko"));
tableBody.replaceChildren();
for (const [key, value] of entries) {
const row = document.createElement("tr");
const keyCell = document.createElement("td");
const valueCell = document.createElement("td");
keyCell.textContent = key;
valueCell.textContent = value;
row.append(keyCell, valueCell);
tableBody.append(row);
}
}
이 예제는 호출 시점의 저장 상태를 배열로 옮긴 뒤 키를 정렬하고, 각 셀에 textContent를 사용합니다. 저장소의 열거 순서와 HTML 해석에 기대지 않기 때문에 테스트 결과가 안정적이고, 태그처럼 보이는 값도 단순 문자열로 표시됩니다.
storage 이벤트는 변경한 탭이 아니라 원격 문서에 전달된다
같은 저장 영역의 값이 바뀌면 그 변경을 일으킨 문서를 제외한 다른 관련 Window에 storage 이벤트가 전달됩니다. 따라서 저장 버튼을 누른 현재 탭은 자신의 화면을 직접 갱신하고, 다른 탭은 이벤트로 따라갑니다. “저장하면 같은 탭에서도 이벤트가 온다”는 가정은 화면 갱신 누락의 원인이 됩니다.
const THEME_KEY = "study-theme";
function applyTheme(theme) {
document.documentElement.dataset.theme = theme;
}
function changeTheme(theme) {
localStorage.setItem(THEME_KEY, theme);
applyTheme(theme); // 변경한 현재 탭은 직접 반영
}
window.addEventListener("storage", (event) => {
if (event.storageArea !== localStorage) return;
if (event.key !== THEME_KEY) return;
applyTheme(event.newValue ?? "light");
});
| 속성 | 의미 | null이 되는 대표 상황 |
|---|---|---|
key | 변경된 키 | clear()로 전체 삭제 |
oldValue | 변경 전 값 | 새 키 추가 |
newValue | 변경 후 값 | 키 삭제 |
url | 변경을 일으킨 문서의 URL | 문자열 URL로 제공 |
storageArea | 영향받은 Storage 객체 | 보통 대상 저장 영역 확인에 사용 |
localStorage는 같은 출처의 다른 탭·창과 동기화에 활용할 수 있습니다. sessionStorage 이벤트는 같은 최상위 탐색 문맥 안에서 저장 영역을 공유하는 문서 사이에 한정되므로 별도 탭 통신 도구로 기대하기 어렵습니다. 또한 localStorage에는 여러 탭의 읽기-수정-쓰기를 원자적으로 잠그는 보장이 없습니다. 두 탭이 동시에 카운터를 읽고 증가시키면 한 번의 증가가 사라질 수 있으므로 중요한 동시성 제어 수단으로 사용하지 않습니다.
위치 요청은 지원·보안·권한·결과의 네 관문을 지난다
Geolocation API는 navigator.geolocation을 통해 현재 위치를 요청합니다. 위치는 민감한 개인정보이므로 보안 컨텍스트에서 명시적인 권한 절차를 거칩니다. 사용자가 거부할 수 있고, 장치나 네트워크가 위치를 구하지 못할 수도 있으므로 성공만 있는 함수로 설계하면 안 됩니다.
- 지원 확인:
navigator.geolocation이 있는지 확인합니다. - 실행 환경: 배포 환경은 HTTPS 같은 보안 컨텍스트인지 확인합니다.
- 사용자 행동: 기능의 목적을 먼저 설명하고 버튼 클릭 등 이해 가능한 시점에 요청합니다.
- 결과 분기: 성공 좌표뿐 아니라 권한 거부·위치 확인 불가·시간 초과를 처리합니다.
브라우저가 권한 창을 표시하는 구체적인 방식과 기억 기간은 환경에 따라 다를 수 있습니다. 애플리케이션이 자체 안내문만 띄웠다고 권한을 얻은 것도 아닙니다. 실제 위치 접근은 브라우저의 권한 결정과 정책을 통과해야 합니다.
개인정보 최소화: 위치가 필요한 순간에만 요청하고, 목적에 필요한 정밀도만 사용하며, 좌표를 서버나 지도 서비스에 넘길 때는 전송 목적과 보존 범위를 별도로 판단합니다.
getCurrentPosition은 성공·실패·옵션의 계약이다
getCurrentPosition(success, error, options)은 위치를 한 번 구합니다. 성공하면 position.coords.latitude, longitude, 미터 단위의 정확도 추정값 accuracy, 위치가 얻어진 시각 timestamp 등을 읽을 수 있습니다. accuracy가 작을수록 더 좁은 범위이지만 좌표가 정확히 그 반지름 안의 중심점이라는 보증으로 과도하게 해석하지 않습니다.
| 옵션 | 질문 | 설계 의미 |
|---|---|---|
enableHighAccuracy | 더 높은 정확도를 요청할 가치가 있는가? | 힌트이며 더 긴 시간·전력 사용 가능 |
timeout | 얼마나 기다린 뒤 실패로 전환할 것인가? | 밀리초 단위 제한 시간 |
maximumAge | 얼마나 오래된 캐시 위치까지 허용할 것인가? | 0이면 새 위치를 요구, 큰 값은 재사용 허용 |
navigator.geolocation.getCurrentPosition(
(position) => {
const { latitude, longitude, accuracy } = position.coords;
console.log({ latitude, longitude, accuracy });
},
(error) => {
const messages = {
1: "위치 권한이 거부되었습니다.",
2: "현재 위치를 확인할 수 없습니다.",
3: "위치 요청 시간이 초과되었습니다."
};
console.warn(messages[error.code] ?? "위치 요청에 실패했습니다.");
},
{
enableHighAccuracy: false,
timeout: 8000,
maximumAge: 60000
}
);
enableHighAccuracy: true가 곧 GPS 사용을 보장하는 것은 아닙니다. 사용자 에이전트가 가능한 최선의 결과를 선택하도록 요청하는 힌트입니다. 근처 지역 정도면 캐시된 위치와 기본 정확도로 충분할 수 있고, 이동 경로처럼 정밀도가 중요한 경우에만 비용을 감수합니다.
콜백 API를 Promise로 감싸면 후속 작업의 실패가 한 줄로 모인다
위치를 얻은 뒤 지도 데이터를 불러오고 화면을 갱신하는 작업이 이어지면 중첩 콜백이 길어질 수 있습니다. Geolocation API 자체는 콜백 기반이므로 Promise 래퍼를 만들면 async/await와 try/catch로 성공 흐름과 오류 흐름을 분리할 수 있습니다.
function getPosition(options = {}) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, options);
});
}
async function findNearbyStudyPlace() {
if (!navigator.geolocation) {
return { ok: false, message: "위치 기능을 지원하지 않습니다." };
}
try {
const position = await getPosition({
enableHighAccuracy: false,
timeout: 8000,
maximumAge: 60000
});
return {
ok: true,
latitude: position.coords.latitude,
longitude: position.coords.longitude
};
} catch (error) {
return { ok: false, code: error.code };
}
}
Promise 래퍼가 권한이나 정확도를 높여 주는 것은 아닙니다. 콜백 결과를 비동기 제어 문법에 맞게 포장할 뿐입니다. 따라서 권한 거부 같은 원래의 오류는 그대로 catch로 들어오며, UI에서는 실패 코드별로 재시도·설정 안내·수동 위치 입력 같은 대안을 제공해야 합니다.
watchPosition은 반복 타이머가 아니라 위치 구독이다
watchPosition()은 위치가 갱신될 때 성공 콜백을 반복 호출하고 감시 ID를 반환합니다. 호출 간격은 고정된 타이머 주기로 보장되지 않습니다. 장치, 이동, 정확도, 캐시와 브라우저 정책에 따라 갱신 시점이 달라질 수 있으므로 “5초마다 정확히 한 번” 같은 로직에 기대지 않습니다.
let watchId = null;
function startTracking(onPosition, onError) {
if (!navigator.geolocation || watchId !== null) return;
watchId = navigator.geolocation.watchPosition(
onPosition,
onError,
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 2000 }
);
}
function stopTracking() {
if (watchId === null) return;
navigator.geolocation.clearWatch(watchId);
watchId = null;
}
window.addEventListener("pagehide", stopTracking);
ID가 null인지 확인해 중복 구독을 막고, 사용자가 중지 버튼을 누르거나 페이지가 끝날 때 clearWatch()를 호출합니다. 높은 정확도 요청과 장시간 추적은 전력과 개인정보 비용이 있으므로 목적이 사라지면 즉시 종료합니다. 중지 뒤 ID를 null로 되돌려 UI 상태와 실제 구독 상태를 일치시킵니다.
상태 전이: 대기 → 권한 요청 → 추적 중 → 중지로 이동합니다. 성공 콜백이 한 번 왔다고 추적이 끝난 것이 아니며, 오류가 발생했을 때 계속 감시할지 종료할지는 서비스 정책으로 결정해야 합니다.
지도 연동은 좌표 획득 뒤의 별도 데이터 전달 단계다
Geolocation API는 위도와 경도를 제공할 뿐 지도를 그리지 않습니다. Leaflet 같은 지도 라이브러리와 OpenStreetMap 같은 타일 데이터를 결합하면 좌표를 중심으로 지도를 표시할 수 있습니다. 이때 위치 획득, 지도 객체 생성, 중심 이동, 마커 갱신은 서로 다른 책임입니다.
function showPositionOnMap(map, marker, position) {
const point = [
position.coords.latitude,
position.coords.longitude
];
map.setView(point, 16);
marker.setLatLng(point).bindPopup("현재 위치").openPopup();
}
지도를 매 위치 갱신마다 새로 생성하지 않고 기존 객체의 중심과 마커를 갱신합니다. 지도 컨테이너에는 CSS로 명시적인 높이를 주어야 화면에 나타납니다. 외부 지도·타일 서비스를 사용할 때는 네트워크 연결, 이용 조건, 저작자 표시와 좌표가 제3자에게 전달될 가능성을 함께 검토합니다.
학습 도우미의 상태 전이를 끝까지 검산한다
| 현재 상태 | 사건 | 다음 상태 | 필수 처리 |
|---|---|---|---|
| 설정 없음 | 최초 로드 | 기본 설정 | null 확인 |
| 정상 설정 | 다른 탭 변경 | 새 테마 반영 | storage의 키·영역 확인 |
| 손상 설정 | JSON 읽기 | 기본 설정 | 파싱·필드 검증 실패 복구 |
| 위치 대기 | 사용자 요청 | 요청 중 | 목적 안내·보안 컨텍스트 |
| 요청 중 | 권한 거부·시간 초과 | 실패 안내 | 코드별 대안 제공 |
| 추적 중 | 중지·페이지 종료 | 추적 종료 | clearWatch()와 ID 초기화 |
이 표의 목적은 메서드를 나열하는 것이 아니라 누락된 전이를 찾는 데 있습니다. 저장 성공만 있고 파싱 실패가 없으면 손상 데이터에서 앱이 멈춥니다. 위치 성공만 있고 거부 상태가 없으면 사용자는 빈 화면을 봅니다. 추적 시작만 있고 종료 상태가 없으면 센서와 권한 사용이 목적보다 길어집니다.
- 민감도: 브라우저 자바스크립트가 읽어도 되는 데이터인지 판정합니다.
- 수명과 공유: 지속 상태인지, 한 탭의 임시 상태인지 정합니다.
- 형식과 실패: 문자열 변환, null, 파싱 오류, 용량·정책 오류를 설계합니다.
- 동기화: 현재 탭은 직접 반영하고 원격 문서는 storage 이벤트로 갱신합니다.
- 위치 목적: 단발 요청인지 구독인지, 필요한 정확도와 캐시 허용 범위를 정합니다.
- 종료와 대안: clearWatch, 권한 거부 안내, 수동 입력 같은 탈출 경로를 둡니다.
핵심 개념 정리
- Web Storage는 문자열 키·값 저장소이며 localStorage는 지속·공유 상태, sessionStorage는 페이지 세션에 묶인 상태에 적합합니다.
- 객체는 JSON으로 왕복하되 키 없음, 파싱 실패와 필드 검증 실패를 서로 다른 상태로 처리합니다.
- 저장 용량은 고정값이 아니며 할당량·정책·출처 문제로 실패할 수 있으므로 쓰기와 접근을 예외 처리합니다.
- storage 이벤트는 변경을 일으킨 문서가 아닌 같은 저장 영역의 다른 관련 문서에 전달되며 동시 쓰기 잠금을 보장하지 않습니다.
- Geolocation은 보안 컨텍스트와 권한을 전제로 하며 성공 좌표, 세 오류 코드와 옵션 비용을 함께 설계합니다.
- getCurrentPosition은 단발 요청, watchPosition은 명시적으로 clearWatch 해야 하는 구독입니다.
최종 판단 공식: 브라우저 상태 API를 사용할 때는 값 자체보다 상태의 수명·공유자·실패·종료를 먼저 그립니다. 저장은 문자열이 된 뒤에도 유효한지 검증하고, 다른 탭과의 동기화는 현재 문서의 직접 갱신과 나눕니다. 위치는 필요한 순간 최소 범위로 요청하고, 거부·시간 초과·추적 종료까지 화면 상태에 포함해야 사용자가 통제할 수 있는 기능이 됩니다.
예상문제 10선
1. 같은 출처에서 브라우저를 닫았다 다시 열어도 유지할 테마 설정과, 한 탭의 다단계 폼 초안에 적합한 조합은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
- ① 오답: sessionStorage는 페이지 세션에 묶여 재실행 뒤 테마 지속 요구와 맞지 않습니다.
- ② 정답: 지속 선호와 탭 단위 임시 작업이라는 서로 다른 수명·공유 범위를 반영합니다.
- ③ 오답: storage는 변경 알림 이벤트이며 값을 저장하는 별도 저장소가 아닙니다.
- ④ 오답: watchPosition은 위치 구독이고 초안의 수명도 불필요하게 길어집니다.
2. localStorage.setItem("count", 7) 뒤 값을 읽어 1을 더하려 한다. 올바른 설명은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
- ① 오답: Storage의 값은 문자열이며 그대로 더하면 문자열 연결이 될 수 있습니다.
- ② 오답: count는 문자열 키이고 key(index)는 인덱스 위치의 키 이름을 구하는 메서드입니다.
- ③ 오답: JSON.stringify는 값을 문자열로 만드는 방향이라 산술 연산 준비와 반대입니다.
- ④ 정답: 문자열 저장 경계를 지나온 값을 명시적으로 숫자로 복원해야 산술 덧셈이 됩니다.
3. 저장된 설정 객체를 안전하게 복구하는 순서로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
- ① 오답: 문자열을 얻기 전에 파싱할 수 없고 저장은 읽기 복구의 필수 단계가 아닙니다.
- ② 오답: 검증 전에 필드를 사용하면 null이나 손상 데이터에서 오류가 납니다.
- ③ 정답: 키 없음, 문법 오류, 의미 오류를 차례로 분리해 기본값 복구를 결정합니다.
- ④ 오답: 전체 삭제는 다른 기능의 데이터까지 잃게 하며 객체 검증 절차가 아닙니다.
4. 설정 저장 시 QuotaExceededError가 발생했다. 가장 적절한 처리 방향은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
- ① 정답: 실패 상태를 UI에 반영하고 데이터 크기·수명·저장소 선택을 다시 판단합니다.
- ② 오답: 같은 조건의 재시도는 할당량 문제를 해결하지 않고 메인 스레드 작업만 반복합니다.
- ③ 오답: clear는 해당 저장 영역 전체를 지워 관련 없는 설정까지 손실시킬 수 있습니다.
- ④ 오답: 위치 API는 저장 용량을 제공하지 않으며 문제 영역도 다릅니다.
5. localStorage를 변경한 직후 화면 동기화 방식으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
- ① 오답: 변경을 일으킨 문서에는 그 변경의 storage 이벤트가 전달되지 않습니다.
- ② 정답: 로컬 반영과 원격 문서 알림이라는 서로 다른 경로를 모두 처리합니다.
- ③ 오답: sessionStorage는 보통 별도 탭과 저장 영역을 공유하지 않습니다.
- ④ 오답: 이벤트는 변경 사실을 알릴 뿐 읽기-수정-쓰기의 원자성을 보장하지 않습니다.
6. storage 이벤트에서 새 키가 추가되었을 때 oldValue는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
- ① 오답: StorageEvent는 이전 값이 없음을 객체가 아니라 null로 나타냅니다.
- ② 정답: 새로 추가된 키에는 변경 전 값이 존재하지 않으므로 null입니다.
- ③ 오답: 새로 저장된 값은
newValue에 들어갑니다. - ④ 오답: 변경을 일으킨 문서 주소는
url속성이 제공합니다.
7. 사용자가 버튼을 눌렀을 때 현재 위치를 한 번만 얻고 싶은 경우 가장 알맞은 메서드는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
- ① 오답: 저장된 문자열을 읽는 메서드이며 센서 위치를 요청하지 않습니다.
- ② 오답: 계속 갱신되는 구독을 만들므로 단발 요구보다 범위가 큽니다.
- ③ 오답: 이미 시작한 위치 감시를 종료할 때 ID와 함께 사용합니다.
- ④ 정답: 성공 또는 실패로 끝나는 한 번의 현재 위치 요청에 맞습니다.
8. 근처 학습 장소를 대략 찾는 기능에서 전력과 응답 시간을 아끼려는 옵션 판단으로 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
- ① 오답: 높은 정확도는 힌트이며 특정 센서, 속도나 성공을 보장하지 않습니다.
- ② 오답: timeout 0은 기다림을 늘리는 값이 아니라 즉시 시간 초과로 이어질 수 있습니다.
- ③ 정답: 목적에 필요한 정밀도와 캐시 신선도·대기 한계를 함께 절충합니다.
- ④ 오답: 캐시 허용 시간은 권한과 별개이며 위치 접근 정책을 우회하지 않습니다.
9. GeolocationPositionError의 코드 1이 뜻하는 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
- ① 정답: 사용자가 거부했거나 정책상 허용되지 않은 권한 상태에 대응합니다.
- ② 오답: 위치 소스를 사용할 수 없는 상태는 코드 2입니다.
- ③ 오답: 정해진 대기 시간을 넘긴 상태는 코드 3입니다.
- ④ 오답: QuotaExceededError는 Web Storage 쓰기와 관련된 별도 오류입니다.
10. 연속 위치 추적의 수명 관리로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
- ① 오답: ID가 없으면 해당 구독을 정확히 종료하기 어렵고 중복 추적이 생깁니다.
- ② 오답: watchPosition은 첫 성공 뒤에도 위치 갱신을 계속 구독합니다.
- ③ 오답: 저장소 삭제는 위치 감시와 연결되지 않으며 사용자 데이터만 잃게 합니다.
- ④ 정답: 시작과 종료를 같은 식별자로 연결하고 UI의 추적 상태도 다시 대기로 돌립니다.
참고 자료와 작성 기준
이 글은 해당 차시 강의자료 58쪽 전체를 확인한 뒤 1~57쪽의 웹 스토리지와 위치 정보 내용을 본문 범위로 삼고, 58쪽의 종강 인사는 학습 범위와 구분했습니다. 슬라이드의 실습 코드를 그대로 옮기지 않고 학습 도우미 앱의 저장·동기화·권한·추적 상태 전이로 재구성한 비공식 학습자료입니다. 고정 저장 용량, 스토리지 이벤트 범위, 높은 정확도 옵션과 위치 갱신 주기는 현행 표준이 보장하는 범위에 맞게 보정했습니다.
- 작성·편집: 올에이클래스 학습연구팀
- 주요 근거: 한국방송통신대학교 HTML5웹프로그래밍 15강 「HTML API: 웹 스토리지, 위치 정보」 강의자료 :codex-file-citation{path="K1. 컴퓨터과학과/1. 재검토필요/2-1 HTML5웹프로그래밍/1. 강의록/HTML5웹프로그래밍_15_강의록.pdf" purpose="source"}
- 보충 자료: WHATWG, HTML Standard: Web storage; W3C, Geolocation; Leaflet, Leaflet API reference (2026-09-05 확인)
- 편집 원칙: 올에이클래스 편집 정책
- 최종 내용 검토: 2026-09-05
댓글
댓글 쓰기