Storage
• 데이터를 영속적으로 저장하거나 아니면 영속적으로 저장된 데이터를 가져와 애플리케이션에서 이용하는것은 애플리케이션에서 가장 기초적면서 가장 빈번하게 작성되는 것 중 하나이다.
백앤드 애플리케이션에서는 영속적인 데이터 저장을 위해 대부분 데이터베이스를 이용하며
오라클, SQL Server, MySQL, MariaDB 부터 클라우드에서 제공하는 데이터베이스까지 많은 데이터베이스들이 있으며 이를 이용해 데이터를 영속적으로 저장해 사용한다.
브라우저에서 데이터를 영속적으로 저장할 수 있는 방법을 제공해야 하고 프런트 자바스크립트에서 WebAPI 를 이용해 프로그램을 작성해 데이터를 영속화 시켜야 한다.
프런트 웹 애플리케이션에서 데이터 영속적 저장을 위해 사용되는 Web API 는 크게 스토리지와IndexedDB 가 있다.
▽ 스토리지(Storage) 저장되는 데이터의 이용 범위에 따라 두개로 구분되어 사용된다.
- 로컬 스토리지 : 동일 오리진의 여러 세션에서 공유되는 스토리지
- 세션 스토리지 : 세션 단위로 이용되는 스토리지
▼ sessionStorage
• 세션이란 웹 애플리케이션이 실행되고 있는 하나의 브라우저 창을 의미하는데
하나의 브라우저 창에서 두 개의 웹 애플리케이션이 실행되었다면 세션도 두 개이다.
또한 동일한 웹 애플리케이션이 두 개의 브라우저 창에서 실행되고 있다면 세션도 두 개이다.
결국 세션 단위로 스토리지가 이용된다는 것은 하나의 창에 떠 있는 하나의 애플리케이션을 위한 스토리지이다.
그러므로 세션이 다르면 스토리지 데이터가 공유되지 않으며 브라우저 창이 종료되면 데이터는 사라진다.
• 만약 window.open() 에 의해 새 창이 열린 경우라고 하면 새로운 창이 기존 창의 세션 스토리지가 복제된다.
하지만 이 경우도 브라우저 창이 두 개가 됨으로 각각의 세션 스토리지는 다른 객체이다.
세션 스토리지는 브라우저가 종료되거나 컴퓨터가 꺼져도 유지되는 데이터를 저장하기에는 부적합하다.
하나의 브라우저 창에서 실행되는 하나의 애플리케이션이 그 브라우저 창이 실행되는 동안 저장했다가 이용할 데이터를 저장하는 용도로 이용해야 한다.
▼ localStorage
• 로컬 스토리지는 동일 오리진의 모든 세션에서 공유할 수 있는 데이터를 저장하기 위해서 사용된다.
로컬 스토리지에 저장된 데이터는 브라우저가 종료되어도 사라지지 않는다.
▼ 스토리지 데이터 저장 및 획득
• Web API 에서는 로컬 스토리지와 세션 스토리지를 위해 각각의 객체를 제공한다.
로컬 스토리지를 이용하고 싶으면 localStorage 객체를, 세션 스토리지를 이용하고 싶으면 sessionStorage라는 객체를 이용하고 객체 명만 다르고 데이터를 저장하거나 획득하는 함수는 동일하다.
- setItem(key, value) : 스토리지 데이터 저장
- getItem(key) : 스토리지 데이터 획득
- removeItem(key) : 스토리지 데이터 삭제
- clear() : 스토리지 내의 모든 데이터 삭제
• 스토리지에 저장되는 키, 값은 모두 문자열 취급한다.
또한 숫자, 객체등을 지정해도 에러가 발생하지는 않지만 숫자, 객체 타입이 유지되지 못하며 문자열로 저장된다.
만약 객체를 저장하고 싶다면 객체를 문자열로 변형해서 저장한다.
<body>
<button onclick="saveSessionStorage()">save session</button>
<button onclick="getSessionStorage()">get session</button>
<br/>
<button onclick="saveLocalStorage()">save local</button>
<button onclick="getLocalStorage()">get local</button>
<br/>
<ul id="result"></ul>
<script src="main.js"></script>
</body>
"use strict"
const saveSessionStorage = function(){
//세션 스토리지에 데이터 저장
sessionStorage.setItem('data1', 'hello')
}
const getSessionStorage = function(){
//세션 스토리지에서 데이터 획득
let value = sessionStorage.getItem('data1')
let resultDom = document.getElementById('result')
resultDom.innerHTML = value
}
const saveLocalStorage = function(){
localStorage.setItem('data2', 'world')
}
const getLocalStorage = function(){
let value = localStorage.getItem('data2')
let resultDom = document.getElementById('result')
resultDom.innerHTML = value
}
▼ 스토리지 데이터 삭제
• 데이터 삭제는 removeItem() 함수를 이용하거나 clear() 함수를 이용한다.
removeItem() 함수를 이용해 매개변수에 지정한 키에 해당되는 데이터만 삭제시킬 수 있으며 clear() 를 이용하면 모든 스토리지 데이터가 삭제된다.
▼ 모든 스토리지 데이터 획득하기
• 스토리지에 저장된 모든 데이터를 획득해야 하는 경우 스토리지의 length 프로퍼티를 이용해 반복문을 작성하고
key() 함수의 매개변수에 인덱스 값을 지정해 해당 위치의 데이터 키 값을 얻을 수 있다.
• 또한 스토리지의 length 를 이용해 반복문을 작성하지 않고
Object.keys() 를 이용해 모든 키를 배열로 획득할 수도 있습니다.
<body>
<button onclick="apiTest()">api test</button>
<button onclick="removeTest()">remove test</button>
<button onclick="getAllDataTest()">all data</button>
<script src="main.js"></script>
</body>
"use strict"
const apiTest = () => {
//sessionStorage, localStorage, 함수 모두 동일
//데이터 저장 구조는 key - value, key 로 식별해서 여러건의 데이터 저장
sessionStorage.setItem('data1', '홍길동')
//key 를 마치 객체의 변수처럼 사용.
sessionStorage.data2 = '김길동'
//문자열이 아닌 각 타입의 데이터 저장시 에러가 나지는 않는다. 데이터 타입 유지 할수 없고 문자열로만 저장된다.
sessionStorage.setItem('data3', 10)
sessionStorage.setItem('data4', {
name: '홍길동',
age: 10
})
console.log('data1', sessionStorage.getItem('data1'))
console.log('data2', sessionStorage.getItem('data2'))
console.log('data3', sessionStorage.getItem('data3'), typeof sessionStorage.getItem('data3'))//data3 10 string
console.log('data4', sessionStorage.getItem('data4'), typeof sessionStorage.getItem('data4'))//data4 [object Object] string
//객체를 storage 에 저장하겠다면
//storage 는 문자열로만 저장됨으로 코드에서 객체를 문자열로 변형해서 저장
//획득시에 다시 객체로 변형해서 사용
sessionStorage.setItem('data5', JSON.stringify({
name: '홍길동',
age: 10
}))
let data5 = JSON.parse(sessionStorage.getItem('data5'))
console.log(data5)
}
const removeTest = () => {
//하나의 데이터 삭제
// sessionStorage.removeItem('data1')
//전체 데이터 삭제
sessionStorage.clear()
}
const getAllDataTest = () => {
//스토리지에 있는 모든 데이터 획득해서 핸들링
// for(let i = 0; i < sessionStorage.length; i++){
// let key = sessionStorage.key(i)//스토리지의 key 를 순차적으로 획득
// console.log(key, sessionStorage.getItem(key))
// }
//아래의 방법으로 전체 데이터 획득할 수도 있고
let keys = Object.keys(sessionStorage)
keys.forEach(key => {
console.log(key, sessionStorage.getItem(key))
})
}
▼ 스토리지 이벤트
• 스토리지는 “storage” 라는 이름의 이벤트를 제공하고 스토리지 데이터가 변경되는 순간 발생하는 이벤트이다.
데이터 변경이란 새로운 스토리지 데이터가 추가되거나 기존 데이터가 수정되거나 혹은 삭제되는 상황을 의미하며
스토리지 데이터를 변경시킨 브라우저 창에서는 이벤트가 발생하지 않는다는 점에서 동일 오리진의 다른 브라우저 창에서 이벤트가 발생하여 어떤 창의 HTML 문서에서 스토리지 데이터를 변경시킨 것을 감지하기 위한 수단으로 이용한다.
• 어느 브라우저 창에서 로컬 스토리지 데이터를 변경했을 때 이 로컬 스토리지를 참조하고 있는 다른 브라우저 창에서 변경 상황을 감지하기 위해서 이벤트가 발생하는 것이다.
세션 스토리의 경우 동일 오리진의 브라우저 창이 여러 개 있다고 하더라도 브라우저 창별로sessionStorage 객체가 따로 유지됨으로 다른 브라우저 창의 세션 스토리지 데이터 변경 이벤트를 감지 할 수 없다.
• 세션 스토리지 데이터 변경 이벤트가 발생하는 경우는 하나의 창에 <iframe> 으로 두개의 HTML 이 실행된 것이다.
• 스토리지 이벤트가 발생되게 되면 이벤트 콜백 함수의 매개변수로 StorageEvent 객체가 전달되는데 이 객체의 프로퍼티로 이벤트와 관련된 다양한 정보를 활용할 수 있다.
- key : 변경된 데이터 키
- newValue : 변경된 데이터 값
- oldValue : 변경되기 전의 데이터 값
- storageArea : 변경된 스토리지 객체, localStorage 혹은 sessionStorage
- url : 데이터 변경을 한 HTML 페이지의 URL
<body>
<h2>Index page</h2>
key <input type="text" id="key"/><br/>
value <input type="text" id="value"/><br/>
<button onclick="saveSessionStorage()">save session</button>
<br/>
<button onclick="saveLocalStorage()">save local</button>
<br/>
<a href="one.html" target="_blank">go one page</a>
<br/>
<button onclick="openNewWindow()">open new window</button>
<br/>
<iframe src="two.html" width="300px" height="200px">
<p>사용중인 브라우저는 iframe 을 지원하지 않습니다.</p>
</iframe>
</body>
<script>
"use strict"
function saveSessionStorage() {
let key = document.getElementById('key').value
let value = document.getElementById('value').value
sessionStorage.setItem(key, value)
}
function saveLocalStorage() {
let key = document.getElementById('key').value
let value = document.getElementById('value').value
localStorage.setItem(key, value)
}
function openNewWindow(){
window.open('one.html')
}
//storage event
window.addEventListener('storage', event => {
console.log('i am index.html')
console.log('스토리지 이벤트 발생')
console.log(`url : ${event.url}`)
if(event.storageArea == sessionStorage){
console.log('sessionStorage event 발생..')
}else if(event.storageArea == localStorage){
console.log('localStorage event..')
}
console.log(`key: ${event.key}, ${event.oldValue} 에서 ${event.newValue} 로 변경`)
})
</script>
<body>
<h2>One Page</h2>
<script src="one.js"></script>
</body>
<script>
window.addEventListener('storage', event => {
console.log('i am one.html')
console.log('스토리지 이벤트 발생')
console.log(`url : ${event.url}`)
if(event.storageArea == sessionStorage){
console.log('sessionStorage event 발생..')
}else if(event.storageArea == localStorage){
console.log('localStorage event..')
}
console.log(`key: ${event.key}, ${event.oldValue} 에서 ${event.newValue} 로 변경`)
})
</script>
<body>
<h2>Two Page</h2>
<script src="two.js"></script>
</body>
<script>
window.addEventListener('storage', event => {
console.log('i am two.html')
console.log('스토리지 이벤트 발생')
console.log(`url : ${event.url}`)
if(event.storageArea == sessionStorage){
console.log('sessionStorage event 발생..')
}else if(event.storageArea == localStorage){
console.log('localStorage event..')
}
console.log(`key: ${event.key}, ${event.oldValue} 에서 ${event.newValue} 로 변경`)
})
</script>
'BootCamp Review' 카테고리의 다른 글
2024.10.10 (Day 23) - File / Web APIs (0) | 2024.10.10 |
---|---|
2024.10.08 (Day 22) - WebSocket / Web APIs (0) | 2024.10.08 |
2024.10.04 (Day 20) - Ajax, Axios / Web APIs (0) | 2024.10.07 |
2024.10.02-04 (Day 19,20) - JavaScript 비동기/ Web APIs (0) | 2024.10.04 |
2024.10.01 (Day 18) - JavaScript OOP / 클로저(Closure) (0) | 2024.10.01 |