JavaScript와 `Web Storage`
이 글에서는 JavaScript와 Web Storage
에 대해 설명합니다.
Web Storage
는 브라우저에서 데이터를 저장하는 강력하고 간단한 메커니즘으로, 주로 localStorage
와 sessionStorage
두 가지로 구성되어 있습니다. 이들의 차이점, 사용법, 그리고 실제 샘플 코드를 단계별로 설명하겠습니다.
YouTube Video
javascript-web-storage-iframe.html
1<!DOCTYPE html>
2<html>
3
4<head>
5 <title>Web Storage Demo</title>
6 <style>
7 * {
8 box-sizing: border-box;
9 }
10
11 body {
12 margin: 0;
13 padding: 1em;
14 padding-bottom: 10em;
15 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16 background-color: #f7f9fc;
17 color: #333;
18 line-height: 1.6;
19 }
20
21 .container {
22 max-width: 800px;
23 margin: 0 auto;
24 padding: 1em;
25 background-color: #ffffff;
26 border: 1px solid #ccc;
27 border-radius: 10px;
28 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
29 }
30
31 .container-flex {
32 display: flex;
33 flex-wrap: wrap;
34 gap: 2em;
35 max-width: 1000px;
36 margin: 0 auto;
37 padding: 1em;
38 background-color: #ffffff;
39 border: 1px solid #ccc;
40 border-radius: 10px;
41 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
42 }
43
44 .left-column,
45 .right-column {
46 flex: 1 1 200px;
47 min-width: 200px;
48 }
49
50 h1,
51 h2 {
52 font-size: 1.2rem;
53 color: #007bff;
54 margin-top: 0.5em;
55 margin-bottom: 0.5em;
56 border-left: 5px solid #007bff;
57 padding-left: 0.6em;
58 background-color: #e9f2ff;
59 }
60
61 button {
62 display: block;
63 margin: 1em auto;
64 padding: 0.75em 1.5em;
65 font-size: 1rem;
66 background-color: #007bff;
67 color: white;
68 border: none;
69 border-radius: 6px;
70 cursor: pointer;
71 transition: background-color 0.3s ease;
72 }
73
74 button:hover {
75 background-color: #0056b3;
76 }
77
78 #output {
79 margin-top: 1em;
80 background-color: #1e1e1e;
81 color: #0f0;
82 padding: 1em;
83 border-radius: 8px;
84 min-height: 200px;
85 font-family: Consolas, monospace;
86 font-size: 0.95rem;
87 overflow-y: auto;
88 white-space: pre-wrap;
89 }
90
91 .highlight {
92 outline: 3px solid #ffc107;
93 /* yellow border */
94 background-color: #fff8e1;
95 /* soft yellow background */
96 transition: background-color 0.3s ease, outline 0.3s ease;
97 }
98
99 .active {
100 background-color: #28a745;
101 /* green background */
102 color: #fff;
103 box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
104 transition: background-color 0.3s ease, box-shadow 0.3s ease;
105 }
106
107 body.dark {
108 background-color: black;
109 color: white;
110 }
111 </style>
112</head>
113
114<body>
115 <button onclick="testLocalStorage()">Test Local Storage</button>
116
117 <script>
118 function testLocalStorage() {
119 // Test operations
120 localStorage.setItem("username", "Alice"); // Save new value
121 localStorage.setItem("username", "Bob"); // Update value
122 localStorage.removeItem("username"); // Remove key
123 localStorage.setItem("theme", "dark"); // Add another key
124 localStorage.clear(); // Clear all data
125 }
126 </script>
127</body>
128
129</html>
javascript-web-storage.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>JavaScript & HTML</title>
6 <style>
7 * {
8 box-sizing: border-box;
9 }
10
11 body {
12 margin: 0;
13 padding: 1em;
14 padding-bottom: 10em;
15 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16 background-color: #f7f9fc;
17 color: #333;
18 line-height: 1.6;
19 }
20
21 .container {
22 max-width: 800px;
23 margin: 0 auto;
24 padding: 1em;
25 background-color: #ffffff;
26 border: 1px solid #ccc;
27 border-radius: 10px;
28 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
29 }
30
31 .container-flex {
32 display: flex;
33 flex-wrap: wrap;
34 gap: 2em;
35 max-width: 1000px;
36 margin: 0 auto;
37 padding: 1em;
38 background-color: #ffffff;
39 border: 1px solid #ccc;
40 border-radius: 10px;
41 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
42 }
43
44 .left-column, .right-column {
45 flex: 1 1 200px;
46 min-width: 200px;
47 }
48
49 h1, h2 {
50 font-size: 1.2rem;
51 color: #007bff;
52 margin-top: 0.5em;
53 margin-bottom: 0.5em;
54 border-left: 5px solid #007bff;
55 padding-left: 0.6em;
56 background-color: #e9f2ff;
57 }
58
59 button {
60 display: block;
61 margin: 1em auto;
62 padding: 0.75em 1.5em;
63 font-size: 1rem;
64 background-color: #007bff;
65 color: white;
66 border: none;
67 border-radius: 6px;
68 cursor: pointer;
69 transition: background-color 0.3s ease;
70 }
71
72 button:hover {
73 background-color: #0056b3;
74 }
75
76 #output {
77 margin-top: 1em;
78 background-color: #1e1e1e;
79 color: #0f0;
80 padding: 1em;
81 border-radius: 8px;
82 min-height: 200px;
83 font-family: Consolas, monospace;
84 font-size: 0.95rem;
85 overflow-y: auto;
86 white-space: pre-wrap;
87 }
88
89 .highlight {
90 outline: 3px solid #ffc107; /* yellow border */
91 background-color: #fff8e1; /* soft yellow background */
92 transition: background-color 0.3s ease, outline 0.3s ease;
93 }
94
95 .active {
96 background-color: #28a745; /* green background */
97 color: #fff;
98 box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
99 transition: background-color 0.3s ease, box-shadow 0.3s ease;
100 }
101
102 body.dark {
103 background-color: black;
104 color: white;
105 }
106 </style>
107</head>
108<body>
109 <div class="container">
110 <h1>JavaScript Console</h1>
111 <button id="executeBtn">Execute</button>
112 <div id="output"></div>
113 </div>
114
115 <div class="container">
116 <h1>IFrame Sample</h1>
117 <iframe src="javascript-web-storage-iframe.html" style="width: 100%;"></iframe>
118 </div>
119
120 <script>
121 // Override console.log to display messages in the #output element
122 (function () {
123 // Override console.log
124 const originalLog = console.log;
125 console.log = function (...args) {
126 originalLog.apply(console, args);
127 const message = document.createElement('div');
128 message.textContent = args.map(String).join(' ');
129 output.appendChild(message);
130 };
131
132 // Override console.error
133 const originalError = console.error;
134 console.error = function (...args) {
135 originalError.apply(console, args);
136 const message = document.createElement('div');
137 message.textContent = args.map(String).join(' ');
138 message.style.color = 'red'; // Color error messages red
139 output.appendChild(message);
140 };
141 })();
142
143 document.getElementById('executeBtn').addEventListener('click', () => {
144 // Prevent multiple loads
145 if (document.getElementById('externalScript')) return;
146
147 const script = document.createElement('script');
148 script.src = 'javascript-web-storage.js';
149 script.id = 'externalScript';
150 //script.onload = () => console.log('javascript-web-storage.js loaded and executed.');
151 //script.onerror = () => console.log('Failed to load javascript-web-storage.js.');
152 document.body.appendChild(script);
153 });
154 </script>
155</body>
156</html>
JavaScript와 Web Storage
Web Storage
란 무엇인가요?
Web Storage
는 클라이언트 측(사용자의 브라우저)에 데이터를 저장하는 API입니다. Cookies
와 달리 Web Storage
는 HTTP 요청과 함께 전송되지 않으며 저장 용량도 더 크기 때문에 데이터 관리가 더욱 효율적입니다.
Web Storage
는 목적에 맞게 사용할 수 있는 두 가지 저장 영역을 제공합니다.
-
localStorage
localStorage
는 영구적인 저장 영역입니다. 브라우저를 닫거나 PC를 재시작해도 데이터가 유지됩니다. 사용자 설정이나 로그인 상태 등 장기간 저장이 필요한 데이터에 적합합니다. -
sessionStorage
sessionStorage
는 임시 저장 영역입니다. 동일 탭 내에서만 유효하며 페이지를 새로고침해도 데이터가 유지되지만, 탭이나 창을 닫으면 자동으로 삭제됩니다. 페이지 간 임시 상태를 유지하는 데 적합합니다.
두 가지 모두 데이터를 키-값 쌍(문자열)으로 저장합니다.
기본 사용법
데이터 저장하기
데이터는 다음과 같이 저장할 수 있습니다:.
1// Save data to localStorage
2localStorage.setItem("username", "JohnDoe");
3
4// Save data to sessionStorage
5sessionStorage.setItem("theme", "dark");
setItem
메서드를 사용하여localStorage
또는sessionStorage
에 키-값 쌍을 저장하세요.
데이터 가져오기
데이터는 다음과 같이 가져올 수 있습니다:.
1const username = localStorage.getItem("username");
2console.log(username); // "JohnDoe"
3
4const theme = sessionStorage.getItem("theme");
5console.log(theme); // "dark"
getItem()
을 사용하여 저장된 값을 읽으세요.
데이터 삭제하기
데이터는 다음과 같이 삭제할 수 있습니다:.
1// Remove a specific key
2localStorage.removeItem("username");
3
4// Clear all data
5sessionStorage.clear();
removeItem()
또는clear()
를 사용하여 저장된 데이터를 삭제하세요.removeItem()
은 지정한 키에 해당하는 데이터만 삭제합니다.clear()
는 저장된 모든 데이터를 삭제합니다.
객체 저장 및 복원하기
Web Storage
는 문자열만 저장할 수 있습니다. 따라서 객체를 저장할 때는 JSON.stringify()
로 문자열로 변환하고, 읽을 때는 JSON.parse()
로 복원해야 합니다.
1const user = {
2 name: "JohnDoe",
3 age: 30
4};
5
6// Save (serialize)
7localStorage.setItem("user", JSON.stringify(user));
8
9// Retrieve (deserialize)
10const savedUser = JSON.parse(localStorage.getItem("user"));
11console.log(savedUser.name); // "JohnDoe"
- 객체를 저장하기 전에
JSON.stringify()
로 문자열로 변환하고, 복원할 때는JSON.parse()
를 사용하세요.
localStorage와 sessionStorage의 차이점 데모
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>Web Storage Demo</title>
5 </head>
6 <body>
7 <input id="input" placeholder="Type your name..." />
8 <button onclick="saveToLocal()">Save to localStorage</button>
9 <button onclick="saveToSession()">Save to sessionStorage</button>
10 <button onclick="showValues()">Show Stored Values</button>
11
12 <script>
13 function saveToLocal() {
14 const value = document.getElementById("input").value;
15 localStorage.setItem("name", value);
16 alert("Saved to localStorage");
17 }
18
19 function saveToSession() {
20 const value = document.getElementById("input").value;
21 sessionStorage.setItem("name", value);
22 alert("Saved to sessionStorage");
23 }
24
25 function showValues() {
26 const local = localStorage.getItem("name");
27 const session = sessionStorage.getItem("name");
28
29 alert(`localStorage: ${local}\nsessionStorage: ${session}`);
30 }
31 </script>
32 </body>
33</html>
1function saveToLocal() {
2 const value = document.getElementById("input").value;
3 localStorage.setItem("name", value);
4 alert("Saved to localStorage");
5}
6
7function saveToSession() {
8 const value = document.getElementById("input").value;
9 sessionStorage.setItem("name", value);
10 alert("Saved to sessionStorage");
11}
12
13function showValues() {
14 const local = localStorage.getItem("name");
15 const session = sessionStorage.getItem("name");
16
17 alert(`localStorage: ${local}\nsessionStorage: ${session}`);
18}
- 이 코드는 입력한 이름을
localStorage
또는sessionStorage
에 저장하고 해당 값을 확인할 수 있는 간단한 데모입니다.
스토리지 이벤트 감시하기
다른 탭에서 같은 localStorage
에 접근하여 데이터가 변경될 때, 한 탭에서 storage
이벤트를 감지할 수 있습니다.
1window.addEventListener("storage", function(event) {
2 console.log("Storage changed!");
3 console.log(`Key: ${event.key}`);
4 console.log(`Old Value: ${event.oldValue}`);
5 console.log(`New Value: ${event.newValue}`);
6});
- 이 이벤트는
localStorage
에만 적용되며,sessionStorage
에는 발생하지 않습니다.
1// Test operations
2localStorage.setItem("username", "Alice"); // Save new value
3localStorage.setItem("username", "Bob"); // Update value
4localStorage.removeItem("username"); // Remove key
5localStorage.setItem("theme", "dark"); // Add another key
6localStorage.clear(); // Clear all data
storage
이벤트는 같은 탭 내에서는 발생하지 않으므로, 다른 탭이나 창에서localStorage
가 수정될 때 이를 감지할 수 있습니다.
실전 예시: 다크 모드 상태 저장하기
1<!DOCTYPE html>
2<html>
3<head>
4 <style>
5 body.dark {
6 background-color: black;
7 color: white;
8 }
9 </style>
10</head>
11<body>
12 <button onclick="toggleDarkMode()">Toggle Dark Mode</button>
13
14 <script>
15 // Load the initial state
16 if (localStorage.getItem("darkMode") === "true") {
17 document.body.classList.add("dark");
18 }
19
20 function toggleDarkMode() {
21 const isDark = document.body.classList.toggle("dark");
22 localStorage.setItem("darkMode", isDark);
23 }
24 </script>
25</body>
26</html>
1// Load the initial state
2if (localStorage.getItem("darkMode") === "true") {
3 document.body.classList.add("dark");
4}
5
6function toggleDarkMode() {
7 const isDark = document.body.classList.toggle("dark");
8 localStorage.setItem("darkMode", isDark);
9}
10
11toggleDarkMode();
- 이 예시에서는 버튼 클릭으로 다크 모드를 ON/OFF 하고, 그 상태가
localStorage
에 저장되어 다음 방문 시 복원됩니다.
저장 용량 제한 및 주의사항
Web Storage
를 사용할 때는 다음 사항을 고려해야 합니다:.
-
저장 용량 제한 브라우저와 환경에 따라 다르지만, 보통 5MB 정도입니다.
-
보안 JavaScript에서 직접 접근할 수 있으므로 민감한 정보 저장에는 적합하지 않습니다.
-
데이터 문자열 변환 모든 데이터가 자동으로 문자열로 저장되므로 타입 정보는 보존되지 않습니다.
1localStorage.setItem("isLoggedIn", true);
2console.log(localStorage.getItem("isLoggedIn")); // "true"(as string)
요약
Web Storage
는 웹 애플리케이션에서 클라이언트 측에 데이터를 임시 또는 영구적으로 저장하는 데 매우 유용한 기능입니다. localStorage
와 sessionStorage
의 차이점과 사용법, 그리고 데이터 저장 및 복원을 위해 JSON.stringify
와 JSON.parse
의 사용 방법을 이해하는 것이 중요합니다. 적절하게 사용하면 사용자 경험을 크게 향상시킬 수 있습니다.
위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.