JavaScript와 `Web Storage`

JavaScript와 `Web Storage`

이 글에서는 JavaScript와 Web Storage에 대해 설명합니다.

Web Storage는 브라우저에서 데이터를 저장하는 강력하고 간단한 메커니즘으로, 주로 localStoragesessionStorage 두 가지로 구성되어 있습니다. 이들의 차이점, 사용법, 그리고 실제 샘플 코드를 단계별로 설명하겠습니다.

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 &amp; 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는 웹 애플리케이션에서 클라이언트 측에 데이터를 임시 또는 영구적으로 저장하는 데 매우 유용한 기능입니다. localStoragesessionStorage의 차이점과 사용법, 그리고 데이터 저장 및 복원을 위해 JSON.stringifyJSON.parse의 사용 방법을 이해하는 것이 중요합니다. 적절하게 사용하면 사용자 경험을 크게 향상시킬 수 있습니다.

위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.

YouTube Video