본문 바로가기
Study/FrontEnd

JavaScript(5)

by 왕방개 2024. 4. 23.

1.ajax

1)개요
=>Asynchronous JavaScript XML(eXtensible Markup Language) 의 약자
=>원래 의미는 비동기적으로 XML 데이터를 가져오는 것이었는데 최근에는 XML 대신에 JSON을 많이 사용

2)사용 이유
=>전체 페이지를 새로고침하지 않고 서버로부터 데이터를 받아서 일부분만 다시 출력하는 용도로 주로 이용
=>여러 콘텐츠를 하나의 화면에서 제공하는 경우에 사용

3)구현 객체
=>XMLHttpRequest

4)알아야 할 내용
=>GET 과 다른 방식으로 데이터를 포함(텍스트, 파일 등)시켜 요청을 전송하고 데이터(JSON, XML, Text 등)가 왔을 때 사용
=>SOP 와 CORS
 - SOP(Same Origin Policy - 동일 출처 정책)
자바스크립트에서 서버에게 데이터를 요청할 때는 동일한 출처인 경우만 가능
동일 출처는 IP 와 Port 까지 일치하는 경우

 - CORS(Cross-Origin Resource Sharing: 교차 출처 정책)
자바스크립트로 접근하는 클라이언트에게 데이터를 제공할 수 있는 기술
이 설정은 서버에서 수행
Web Application을 구현할 때 서버 와 클라이언트를 별도로 구현하는 경우에는 서버에서 설정을 해 줄 수 있습니다.

 - Proxy
서버 와 클라이언트를 하나의 애플리케이션으로 구현할 때 클라이언트에서 직접 외부 서버에 요청을 하지 않고 자신의 서버에게 요청을 보내고 서버가 다른 서버에서 데이터를 받아서 클라이언트에게 전송하는 방식
react에서는 프록시 설정을 이용해서 외부에서 데이터를 받아올 수 있습니다.
react 가 node 플랫폼에서 수행이 되므로 node의 다른 라이브러리를 이용해서 외부 서버에서 데이터를 받아오는 것입니다.

 

5)텍스트 파일(CSV)을 GET 방식으로 가져오기
=> 현재 프로젝트에 data 디렉토리를 만들고 data.csv 파일을 만들고 내용을 작성

=> html 파일을 생성하고 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>자바스크립트</title>
    <script>
        //스크립트 와 태그는 순서대로 읽어가면서 수행하기 때문에 아래있는 DOM 객체를
        //사용하고자 하면 DOM이 전부 메모리에 로드된 후 사용을 해야 합니다.
        window.addEventListener("load", e => {
            let display = document.getElementById("display");

            //ajax 객체 생성
            let request = new XMLHttpRequest();

            //요청을 생성
            request.open("GET", "data/data.csv");

            //요청을 전송: 파라미터가 있는 경우 '' 대신에 파라미터를 전송
            request.send('');

            //정상적으로 요청이 처리된 경우
            request.addEventListener("load", () => {
                //텍스트는 request.responseText로 읽기 가능
                display.innerHTML = request.responseText;
            });

            //정상적으로 처리가 되지 않는 경우
            request.addEventListener("error", () => {
                //로컬에 이전 데이터를 저장해두고 이전 데이터를 출력하는 것도 하나의 방법
                display.innerHTML = "에러 발생";
            });
        })
    </script>
</head>
<body>
   
    <div id="display"></div>
   
</body>
</html>

 

=> 실행하면 CORS 에러가 발생
 - 이전에는 이 에러가 발생하지 않았는데 최신 브라우저를 사용하면 에러가 발생
 - 이 경우는 서버 형태로 실행하고 파일을 출력하면 에러가 없어집니다.
 
=>해결책
 - node 설치
 - 서버를 구동할 수 있는 패키지를 설치: npm install http-server -g
 - 프로젝트 실행: npx http-server -p 포트번호(포트번호 생략하면 8080)
 - 127.0.0.1:포트번호/파일경로 로 브라우저에서 접근

6)JSON Parsing
=>JSON.parse 메서드에 JSON 문자열을 대입하면 JavaScript 객체로 리턴
=>JavaScript 데이터를 JSON 문자열로 만들고자 하는 경우는 JSON.stringify: 파라미터를 만드는 경우 사용
=>서버에서 데이터를 전송할 때 되도록이면 데이터의 존재 여부 나 작업 결과를 같이 전송하는 것이 좋습니다.

 

=>data 디렉토리에 data.json 파일을 생성하고 작성
{
    "result": "success",
    "data":["시모나", "카프치노"]
}

 

=>html 파일에 스크립트 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>자바스크립트</title>
    <script>
        //스크립트 와 태그는 순서대로 읽어가면서 수행하기 때문에 아래있는 DOM 객체를
        //사용하고자 하면 DOM이 전부 메모리에 로드된 후 사용을 해야 합니다.
        window.addEventListener("load", e => {
            let display = document.getElementById("display");

            //ajax 객체 생성
            let request = new XMLHttpRequest();

            //요청을 생성
            request.open("GET", "data/data.json");

            //요청을 전송: 파라미터가 있는 경우 '' 대신에 파라미터를 전송
            request.send('');

            //정상적으로 요청이 처리된 경우
            request.addEventListener("load", () => {
                //JSON 문자열을 자바스크립트 객체로 변환
                let obj = JSON.parse(request.responseText);
                alert(obj.result);

                if(obj.result === "success"){
                    //자바스크립트에서 for-in 은 인덱스나 속성을 리턴
                    for(let imsi of obj.data){
                        console.log(imsi);
                    }
                }else{
                    alert("데이터를 가져오지 못함");
                }
            });

            //정상적으로 처리가 되지 않는 경우
            request.addEventListener("error", () => {
                //로컬에 이전 데이터를 저장해두고 이전 데이터를 출력하는 것도 하나의 방법
                display.innerHTML = "에러 발생";
            });
        })
    </script>
</head>
<body>
   
    <div id="display"></div>
   
</body>
</html>

 

7)XML 파싱


=>JSON 과 일반 텍스트는 responseText 속성을 이용해서 데이터를 읽어내지만 XML은 responseXML 속성을 이욯해서 읽어야 하고 getElementsByTagName - 배열 리턴 이나 getElementById  속성을 이용해서 데이터를 찾아올 수 있고 nodeValue를 이용해서 태그 안의 값에 접근
=>서버를 직접 만드는 경우에는 되도록이면 XML을 사용하지 않는 것을 권장하고 외부 API를 사용하는 경우가 아니라면 실제 사용은 드뭄 

=>data.xml 파일을 만들고 작성

<?xml version="1.0" encoding="utf-8"?>

<NewFriends>
    <friend>
        <name>난이</name>
        <address>등촌동</name>
    </friend>
    <friend>
        <name>시모나</name>
        <address>오목교</name>
    </friend>
    <friend>
        <name>카푸치노</name>
        <address>염창동</name>
    </friend>
</NewFriends>

 

=>스크립트 코드 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>자바스크립트</title>
    <script>
        //스크립트 와 태그는 순서대로 읽어가면서 수행하기 때문에 아래있는 DOM 객체를
        //사용하고자 하면 DOM이 전부 메모리에 로드된 후 사용을 해야 합니다.
        window.addEventListener("load", e => {
            let display = document.getElementById("display");

            //ajax 객체 생성
            let request = new XMLHttpRequest();

            //요청을 생성
            request.open("GET", "data/data.xml");

            //요청을 전송: 파라미터가 있는 경우 '' 대신에 파라미터를 전송
            request.send('');

            //정상적으로 요청이 처리된 경우
            request.addEventListener("load", () => {
                //XML 데이터를 DOM 객체로 받기
                let obj = request.responseXML;
                //원하는 태그를 DOM 객체 배열로 만들기
                let names = obj.getElementsByTagName("name");
                let addresses = obj.getElementsByTagName("address");
                /*
                for(let name of names){
                    console.log(name.childNodes[0].nodeValue)
                }
                */

                for(let i=0; i<names.length; i++){
                    let name = names[i].childNodes[0].nodeValue;
                    let address = addresses[i].childNodes[0].nodeValue;
                    console.log(name + ":" + address)
                }
               
            });

            //정상적으로 처리가 되지 않는 경우
            request.addEventListener("error", () => {
                //로컬에 이전 데이터를 저장해두고 이전 데이터를 출력하는 것도 하나의 방법
                display.innerHTML = "에러 발생";
            });
        })
    </script>
</head>
<body>
   
    <div id="display"></div>
   
</body>
</html>

 

8)파라미터 전송
=>parameter: 클라이언트가 서버에게 전송하는 데이터
=>전송 방식에 따라 크게 2가지로 나누고 요즈음은 조금 더 세분화해서 사용
GET: 조회할 때 사용하는데 파라미터를 URL 뒤에 붙이는 방식

POST: 삽입할 때 사용하는 방식으로 파라미터를 헤더에 포함시켜 전송
PUT: 수정할 때 사용하는 방식으로 파라미터를 헤더에 포함시켜 전송
DELETE: 삭제할 때 사용하는 방식으로 파라미터를 헤더에 포함시켜 전송

=>GET을 이용해서 하나의 데이터만 조회하는 경우 와 DELETE의 경우는 파라미터가 기본키 한 개인 경우가 많아서 이런 경우에는 파라미터를 URL에 포함시켜서 사용하는 방식을 많이 사용
=>GET은 URL 뒤에 붙이는 방식이라서 파라미터 조회가 가능하고 글자 수 제한(128자)이 있음

=>GET 요청의 파라미터 전송
- URL: https://jsonplaceholder.typicode.com/comments?postId=1
- 파라미터는 postId 이고 값은 숫자
- GET 방식의 경우는 뒤에 붙이기만 하면 되는데 한글이나 공백이 포함된 경우에는 인코딩해서 전송

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>자바스크립트</title>
    <script>
        //스크립트 와 태그는 순서대로 읽어가면서 수행하기 때문에 아래있는 DOM 객체를
        //사용하고자 하면 DOM이 전부 메모리에 로드된 후 사용을 해야 합니다.
        window.addEventListener("load", e => {
            let display = document.getElementById("display");

            //ajax 객체 생성
            let request = new XMLHttpRequest();

            //요청을 생성
            request.open("GET", "https://jsonplaceholder.typicode.com/comments?postId=1");

            //요청을 전송: 파라미터가 있는 경우 '' 대신에 파라미터를 전송
            request.send('');
            //정상적으로 요청이 처리된 경우
            request.addEventListener("load", () => {
                //JSON 문자열이 객체의 배열이고 객체 안에서 email 추출
               let ar = JSON.parse(request.responseText);
               for(let data of ar){
                console.log(data.email);
               }
            });

            //정상적으로 처리가 되지 않는 경우
            request.addEventListener("error", () => {
                //로컬에 이전 데이터를 저장해두고 이전 데이터를 출력하는 것도 하나의 방법
                display.innerHTML = "에러 발생";
            });
        })
    </script>
</head>
<body>
   
    <div id="display"></div>
   
</body>
</html>

 

=>POST 방식의 파라미터 전송: form의 데이터 전송
- new FormData()로 FormData 객체를 생성
기존 Form이 존재하면 생성자의 매개변수로 Form의 DOM을 대입

만들어지니 객체.append(속성이름, 값) 의 형태로 FormData 객체를 편집

Header 설정을 하고 이 내용을 이름=값& 형태로 변환해서 send에 대입

https://jsonplaceholder.typicode.com/posts 에 POST 방식으로 요청을 하면 입력한 파라미터를 다시 전송해줍니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>자바스크립트</title>
    <script>
        //스크립트 와 태그는 순서대로 읽어가면서 수행하기 때문에 아래있는 DOM 객체를
        //사용하고자 하면 DOM이 전부 메모리에 로드된 후 사용을 해야 합니다.
        window.addEventListener("load", e => {
           //버튼 찾아오기
           let btn = document.getElementById("btn");
           //폼 찾아오기
           let myform = document.getElementById("myform");

           //버튼 클릭 이벤트 처리
           btn.addEventListener("click", (e) => {
            //ajax 요청
            let request = new XMLHttpRequest();
            //요청 생성
            request.open("POST", "https://jsonplaceholder.typicode.com/posts");
            //POST 방식의 파라미터 만들기
            let formdata = new FormData(myform);
            formdata.append("address", "오목교");
            request.setRequestHeader("Content-type", 
        "application/x-www-form-urlencoded");
            let param = "";
            for(let pair of formdata.entries()){
                param += pair[0] + '=' + pair[1] + "&";
            }
            request.send(param);

            request.addEventListener("load", (e) => {
                console.log(request.responseText);
            })
           })
        })
    </script>
</head>
<body>
   
    <form id="myform">
        이름:<input type="text" id="name"  name="name"/>
    </form>
    <button id="btn">전송</button>
   
</body>
</html>

- form에 file이 있는 경우는 FormData를 변환할 필요없이 바로 전송
form을 만들 때 file이 있으면 enctype="multipart/form-data" 로 설정을 하기 때문에 변환할 필요가 없습니다.


=>PUT이나 DELETE 방식은 POST 와 동일

 

2.Fetch API

1)개요
=>ajax 이후에 추가된 비동기 통신 방식
=>설정 방식: https://developer.mozilla.org/en-US/docs/Web/API/fetch
=>사용방식
fetch("URL", Option)
.then((response) => 성공했을 때 수행할 함수를 호출)
.then((함수를 호출한 결과) => 처리 내용)
.then...

catch((e) => 예외가 발생했을 때 처리 내용)
=>ajax는 콜백을 이용하기 때문에 복잡한 요청을 하게되면 코드를 알아보기가 어려운데 fetch API를 사용하면 간결하게 코드를 작성할 수 있음

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>자바스크립트</title>
    <script>
        //스크립트 와 태그는 순서대로 읽어가면서 수행하기 때문에 아래있는 DOM 객체를
        //사용하고자 하면 DOM이 전부 메모리에 로드된 후 사용을 해야 합니다.
        //일반적으로 요청을 하고 첫번째 처리 문장은 거의 동일
        //두번째 then에서 받은 데이터를 가지고 무엇을 할 지 결정하면 됩니다.
        window.addEventListener("load", e => {
          fetch('data/data.json')
          .then((response) => response.json())
          .then((data) => console.log(data))
        })
    </script>
</head>
<body>
   
    <form id="myform">
        이름:<input type="text" id="name"  name="name"/>
    </form>
    <button id="btn">전송</button>
   
</body>
</html>

3.axios 라이브러리

=>ajax 나 fetch API를 대신하는 자바스크립트 라이브러리
=>ajax 나 fetch API 보다 사용하는 코드가 간결합니다.
내부적으로 fetch API 나 ajax로 변환해서 작업을 수행합니다.


   

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        //스크립트 와 태그는 순서대로 읽어가면서 수행하기 때문에 아래있는 DOM 객체를
        //사용하고자 하면 DOM이 전부 메모리에 로드된 후 사용을 해야 합니다.
        //일반적으로 요청을 하고 첫번째 처리 문장은 거의 동일
        //두번째 then에서 받은 데이터를 가지고 무엇을 할 지 결정하면 됩니다.
        window.addEventListener("load", e => {
            axios({
                method: 'get',
                url: 'data/data.json'
            })
            .then(function (response) {
                //json 파싱된 결과를 전송
               console.log(response.data)
            });
        })
    </script>



'Study > FrontEnd' 카테고리의 다른 글

React 서버 연동  (0) 2024.04.29
React  (1) 2024.04.26
JavaScript(4)  (0) 2024.04.23
JavaScript(3)  (1) 2024.04.18
React(3)  (0) 2024.01.31