[Web-Front] WebStorage, AJAX

Bzeromo·2023년 10월 25일
0

HTML/CSS/JavaScript

목록 보기
4/5
post-thumbnail

⚡ WebStorage, AJAX


📌 Web Storage API

🔷 키 / 값 쌍으로 값을 저장

🔷 SessionStorage: 각각의 출처에 대해 독립적인 저장 공간을 페이지 세션이 유지되는 동안(브라우저가 열려있는 동안) 제공

  • 세션에 한정해, 즉 브라우저 또는 탭이 닫힐 때까지만 데이터를 저장한다.
  • 데이터를 절대 서버로 전송하지 않는다.
  • 저장 공간이 쿠키보다 크다.

🔷 localStorage: 세션과 다르게 브라우저를 닫았다 열어도 데이터가 남아있다.

  • 유효기간 없이 데이터를 저장하고, JavaScript를 사용하거나 브라우저 캐시 또는 로컬 저장 데이터를 지워야만 사라진다.
  • 저장 공간이 쿠키, 세션보다 크다.

🔷 Storage 속성

  • length : 객체에 저장된 데이터 항목의 수를 반환

🔷 Storage 메서드

  • key(index) : index 번째의 키를 반환
  • getItem(key) : key에 해당하는 값 반환
  • setItem(key, value) : key가 존재하는 경우 재설정, 존재하지 않는 경우 추가
  • removeItem(key) : key를 저장소에서 제거
  • clear() : 모든 키를 저장소에서 제거

⭐ 실습

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로컬스토리지 실습</title>
</head>
<body>
    <h1>로컬스토리지</h1>
    <input type="text" id="input" placeholder="내용 입력"/>
    <button id="create">등록</button>
    <button id="read">조회</button>
    <button id="delete">삭제</button>
    <hr>
    <h2>내용</h2>
    <div id ="save">

    </div>
    <script>
        window.addEventListener("load", () => {
            let data = localStorage.getItem("JSON data")

            if(data != null) {
                document.querySelector("#save").innerText = JSON.parse(data);
            }
        });
    </script>
    
    <script>
        //등록
        let createBtn = document.querySelector("#create")
        createBtn.addEventListener("click", function() {
            let $inputTag = document.querySelector("#input");
            console.log($inputTag.value);

            //데이터 저장을 위한 로컬 스토리지
            //(String, String), input 데이터가 문자열이라 그대로 사용 가능
            //localStorage.setItem("data", $inputTag.value);

            //객체를 문자열로 만들어 넣고 싶다면?
            let jsonData = JSON.stringify($inputTag.value);
            localStorage.setItem("JSON data", jsonData);

            $inputTag.value = "";
        });
        
        //조회
        document.querySelector("#read").addEventListener("click", () => {
            let $saveTag = document.querySelector("#save");
            
            //데이터 찾기
            //찾고자하는 key가 없으면 null이 반환
            let $jsonData = localStorage.getItem("JSON data");

            if($jsonData != null) {
                let data = JSON.parse($jsonData);
                $saveTag.innerText = data;
            }
        });
        
        //삭제
        document.querySelector("#delete").addEventListener("click", () => {
            localStorage.removeItem("JSON data")
            document.querySelector("#save").innerText = "";
        });
    </script>
</body>
</html>

기본 화면

데이터 추가

데이터 조회

로컬 저장소에 저장된 데이터는 새로 고침을 해도 데이터가 남는다!

데이터 삭제


📌 AJAX

🔷 JavaScript는 Single thread!

  • 이벤트를 처리하는 Call Stack이 하나
  • 즉시 처리하지 못하는 이벤트들을 (Web API)로 보내서 처리
  • 처리된 이벤트들은 처리된 순서대로 대기 줄(Task queue)에 저장
  • Call Stack이 공백이 되면 (Event Loop)가 대기 줄에서 가장 오래된 이벤트를 Call Stack으로 보냄

🔷 AJAX (Asynchronous JavaScript and XML)

  • 비 동기식 JavaScript와 XML
  • 서버와 통신을 하기 위해서 XMLHttpRequset 객체를 활용
  • JSON, XML, HTML 그리고 일반 텍스트 형식 등을 포함한 다양한 포맷을 주고 받을 수 있음.
  • 페이지 전체를 ‘새로고침’ 하지 않고서도 수행 되는 “비동기성” (일 부분만 업데이트 가능)

💡 동기식은 서버에서 요청한 데이터가 도착할 때까지 클라이언트가 대기하지만 비동기식은 서버에 요청한 데이터가 도착할 동안 클라이언트가 멈추지 않고 동작한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        console.log('hi');
        setTimeout(() => {
            console.log("대기 완료");
        }, 3000)
        console.log("bye");

        setInterval(() => {
            let bgColor = document.body.style.background;
            if(bgColor == "red")
             document.body.style.background = "yellow"
            else
            document.body.style.background = "red"
        }, 100)
    </script>
</body>
</html>

**현란하게 번쩍이는 노랑 빨강 불빛을 보다보면 콘솔에는 3초 뒤에 "대기 완료"가 뜬다.

🔷 순차적인 비동기 처리하기

  • Web API로 들어오는 순서는 중요하지 않고, 어떤 이벤트가 먼저 처리되느냐가 중요. (실행 순서 불명확)

1. Async Callbacks

  • 백그라운드에서 실행을 시작할 함수를 호출할 때 인자로 지정
  • ex) addEventListener() 의 두 번째 인자

2. Promise-Style

  • Modern Web APIs에서의 새로운 코드 스타일
  • XMLHttpRequest 객체를 사용하는 구조보다 조금 더 현대적인 버전

🔷 XMLHttpRequest 객체

  • JavaScript Object
  • 서버와 상호작용하기 위해 사용
  • 전체 페이지의 새로고침 없이도 URL로 부터 데이터를 받아 올 수 있음.
  • 사용자의 작업을 방해하지 않고 페이지의 일부를 업데이트 할 수 있음.
  • AJAX 프로그래밍에 주로 사용
  • XML이라는 이름과는 달리 모든 종류의 데이터를 받아 오는데 사용 가능
  • http 이외의 프로토콜도 지원 (file, ftp 포함)
  • 대부분의 브라우저에서 지원

⭐ XMLHttpRequest 객체의 메서드들

1.open(“HTTP method”, “URL”, sync/async)

  • 요청의 초기화 작업
  • GET / POST 지정
  • 서버 URL 지정
  • 동기 / 비동기 설정

2. send(content)

  • GET 방식은 URL에 필요 정보를 추가 하기 때문에 null 적용
  • POST 방식에 서 파라미터 설정 처리

⭐ XMLHttpRequest 객체 프로퍼티들

1. onreadystatechange

  • 서버에서 응답이 도착했을 때 호출될 콜백함수 지정
  • 콜백함수는 상태(readyState)가 변경될 때 마다 호출

2. readyState

  • 0 → UNSENT (객체 생성 후 open 메서드 호출 전)
  • 1 → OPEND (open 메서드가 호출되고 send 호출 전)
  • 2 → HEADERS_RECEIVED (send 메서드가 호출되었지만 서버 응답 전, 헤더와 상태 확인 가능)
  • 3 → LOADING (다운로드 중, 데이터의 일부가 전송된 상태)
  • 4 → DONE (모든 데이터 전송 완료)

3. status

  • 서버 처리 결과 상태 코드
  • 200 → OK (요청 성공
  • 404 → Not Found (페이지를 못 찾을 경우
  • 500 → Server Error (서버에서 결과 생성시 오류 발생)

4. responseText

  • 서버의 응답결과를 문자열로 받기

5.responseXML

  • 서버의 응답결과를 XML Document로 받기

⭐ AJAX 프로그래밍 순서

  1. 클라이언트 이벤트 발생
  2. XMLHttpRequest 객체 생성
  3. XMLHttpRequest 객체 콜백함수 설정
  4. XMLHttpRequest 객체를 통한 비동기화 요청
  5. 서버 응답결과를 생성하여 클라이언트로 전송
  6. XMLHttpRequest 객체는 서버 결과를 처리할 콜백함수 호출
  7. 결과를 클라이언트 화면에 반영

💡 실습에는 JSON placeholder를 사용한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        const URL = "https://jsonplaceholder.typicode.com/todos/1"
        
        //AJAX 통신
        const xhr = new XMLHttpRequest();

        //xhr을 통해 서버에 요청 보내기
        xhr.open('GET', URL); //초기화
        xhr.send();
      
        const todo = xhr.response;
        console.log(todo);
    </script>

</body>
</html>

싱글 스레드 특성상 todo에는 응답이 돌아오지 않아 저장된 것이 없고, 콘솔에 response를 직접 찍으면 나온다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        const URL = "https://jsonplaceholder.typicode.com/todos/1"
        
        //AJAX 통신
        const xhr = new XMLHttpRequest();

        //xhr을 통해 서버에 요청 보내기
        xhr.open('GET', URL); //초기화
        xhr.send();

        //해당 속성은 상태가 바뀔 때 마다 수행할 콜백메서드를 지정한다.
        xhr.onreadystatechange = () => {
            if(xhr.readyState == 4/*xhr.DONE*/) {
                if(xhr.status == 200) {
                    const todo = xhr.response;
                    console.log(todo);
                }
            }
        }
    </script>

</body>
</html>

이제는 정상적으로 찍힌다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>서버에 요청 보내고 받아서 화면 출력</h2>
    <div id = "view"></div>
    <button id="submit">요청</button>

    <script>
        let xhr;
        //클라이언트에서 요청이 발생한다.
        document.querySelector("#submit").addEventListener('click', () => {
            //xhr 객체 생성
            xhr = new XMLHttpRequest();
            xhr.onreadystatechange = responseMsg;
            //xhr객체 초기화(URL 입력, 메소드 방식 설정)
            //true는 비동기 방식의 여부
            xhr.open('GET', './data/hello.txt', true);
            //요청 보내기
            xhr.send();
        })

        //AJAX 요청에 대한 응답이 왔을 때 사용할 콜백함수
        function responseMsg() {
            //응답 종료 시
            if(xhr.readyState == 4) {
                //서버에서 오류 없이 정상적으로 처리가 되었을 때
                if(xhr.status == 200) {
                    document.querySelector("#view").innerHTML = xhr.response;
                } else {
                    console.log("데이터 받기 실패!")
                }
            }
        }
    </script>

</body>
</html>

이런 식으로 응용할 수도 있다.

👍 그 외 JavaScript를 이용한 비동기 제어 관련하여 포스팅을 많이 해두었으니 이를 참고하길 바란다. JS 시리즈


한 때 프론트엔드가 꿈이었던 내가 조금씩 백엔드로 마음을 돌리게 한 것 중의 하나가 비동기 개념이었는데, 뭐 다시 보니 쉬운 것 같기도 하고...

profile
Hodie mihi, Cras tibi

0개의 댓글