All'alba vincerò

At dawn, I will win!

Javascript/Coding Apple

[Coding Apple] 상품 더보기 / Ajax

나디아 Nadia 2024. 3. 6. 23:42

 

 

상품 더보기 / Ajax

 

 

 

서버

: 유저가 데이터 달라고 요청을 하면 데이터를 보내주는 간단한 프로그램

  • 서버와 유저는 문자 자료만 주고 받을 수 있다.

 

서버에 데이터를 요청 시

  • 확인
    1. 어떤 데이터인지 url로 기재
    2. 어떤 방법으로 요청할지 결정(GET/POST 등)

 

  • GET 요청
    : 서버에 있던 데이터 읽기

    - 브라우저 주소창에 url 적으면 그 곳으로 GET요청을 날린다.
  • POST요청
    : 서버로 데이터 보내기

    - <form action="요청할url" method="post"> 태그로 폼이 전송되었을 때 POST요청을 날린다.

  • 단점: GET / POST 요청 시 브라우저가 새로고침 됨
    => Ajax 사용

 

 

 

Ajax

(Asynchronous JavaScript And XML = 비동기 자바스크립트와 XML)

: 서버에 GET, POST 요청을 할 때, 새로고침 없이 데이터를 주고받을 수 있게 도와주는 기능

  • 순수 Javascript로 Ajax통신을 할 때는 XMLHttpRequest라는 API를 이용한다.
  • html 파일을 미리보기로 띄워야 사용 가능
    (127.0.0 or localhost)

 

fetch() 함수

  • 브라우저 기본 함수
  • 배열(array, object)를 보내고 싶으면 JSON 파일로 만들어야 함
    (따옴표를 붙여서 문자처럼 만들기("{"price" : 5000}")
  • 첫번째 인자로 URL, 두번째 인자로 옵션 객체를 받고, Promise 타입의 객체를 반환
  • API 호출이 성공했을 경우 console.log(data) 반환, 실패했을 경우  console.log(error) 반환
fetch('api 주소')
    .then(res => res.json()) // 받아온 데이터를 -> JSON 형식으로 파싱
    .then(data => { // JSON 데이터를 받아 처리
        console.log(data)
    })
    .catch(error =>{
        console.log(error)
    })

 

 

 

 

GET 요청

  1. XMLHttpRequest()를 실행하여 통신에 사용될 XMLHttpRequest(XHR) 객체를 생성한다.
  2. .open()으로 생성된 객체에 요청을 초기화한다.
    • open('전송 방식', 'url', '비동기 여부')
  3. .send()로 요청을 전송한다.
  4. .onload로 통신 후 콜백(Callback) 처리한다.
  5. .status는 XHR객체의 응답 상태를 반환한다. (통신 성공 시 200 반환)
  6. .response를 사용하면 서버에서 전송한 데이터를 사용할 수 있다.
var btn = document.getElementById("btn-ajax");

btn.addEventListener("click", () => {
  
  // 1. XMLHttpRequest 객체 생성
  var xhr = new XMLHttpRequest();

  // 2.  생성된 객체에 요청을 초기화
  xhr.open('GET', 'url', true);

  // 3. 요청 전송
  xhr.send();

  // 4. 통신 후 콜백(Callback) 처리
  xhr.onload = () => {
    // XHR객체의 응답 상태를 반환
    if (xhr.status == 200) {
      // 성공
      console.log(xhr.response);
      // 서버에서 전송한 데이터를 사용 가능
    } else {
      // 실패
    }
  }
});

 

 

 

 

POST 요청

1. XMLHttpRequest()를 실행하여 통신에 사용될 XMLHttpRequest(XHR) 객체를 생성한다.

2. .open()으로 생성된 객체에 요청을 초기화한다.

  • open('전송 방식', 'url', '비동기 여부

3. .setRequestHeader()를 통해 헤더 설정을 추가한다.
4. 전송할 데이터를 .send() 안에 넣어 요청을 전송한다.
5. .onload로 통신 후 콜백(Callback) 처리한다.
6. .status는 XHR객체의 응답 상태를 반환한다. (통신 성공 시 200 반환)
7. .response를 사용하면 서버에서 전송한 데이터를 사용할 수 있다.

var btn = document.getElementById("btn-ajax");

btn.addEventListener("click", () => {
  
  // 1. XMLHttpRequest 객체 생성
  var xhr = new XMLHttpRequest();

  // 2.  생성된 객체에 요청을 초기화
  xhr.open('POST', 'url', true);
  
  // 3. HTTP 요청 헤더 설정
  xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        
  // 4. 요청 전송
  xhr.send("id=post_ajax");

  // 5. 통신 후 콜백(Callback) 처리
  xhr.onload = () => {
    // XHR객체의 응답 상태를 반환
    if (xhr.status == 200) {
      // 성공
      console.log(xhr.response);
      // 서버에서 전송한 데이터를 사용 가능
    } else {
      // 실패
    }
  }
});

 

 

 


 

 

상품 더보기

 

구현 계획 

 

1. 상품 목록 만들기

  • 1-1. 데이터 배열 순환하기
  • 1-2. 데이터만큼 카드 더 만들기
var products = [
    { id : 0, price : 80000, title : 'Blossom Dress' },
    { id : 1, price : 50000, title : 'Spring Shirt' },
    { id : 2, price : 60000, title : 'Black pants' }
];

products.forEach((a, i) => {
    var a = 
        `<div class="col-sm-4">
            <img src="https://via.placeholder.com/600" class="w-100">
            <h5>${products[i].title}</h5> 
            <p>가격 : ${products[i].price}</p>
         </div>`;

    document.querySelector('.row').insertAdjacentHTML('beforeend', a);
});

 

 

 

 

2. 상품 더보기 버튼

 

1. 데이터를 가져올 페이지를 나타내는 변수를 선언한다.
2. fetch 함수를 사용하여 해당 URL에서 데이터를 가져온다. 

  • 2-1. URL에 ${page}를 사용하여 페이지 번호를 동적으로 설정한다.
    fetch(`https://codingapple1.github.io/js/more${page}.json`)
  • 2-2. 오류가 발생하면 콘솔에 오류를 기록한다.
    .catch(error => {...  (fetch 함수 구조)

3. 데이터가 있는지 확인한다.

  • 3-1. 가져올 데이터가 있는 경우
    if (data.length > 0) { 
    (1) 가져온 데이터 배열을 순회하면서 각 항목마다 HTML 생성한다.
    (2) HTML 요소에 데이터를 추가한 HTML을 추가한다. (.insertAdjacentHTML())
    (3) 다음에 가져올 페이지를 설정하기 위해 페이지 변수를 증가시킨다.
  • 3-2. 가져올 데이터가 없는 경우
    (1) 더보기 버튼을 비활성화한다.
    .disabled = true : 버튼 활성화/비활성화 기능 (disabled =true면 비활성화, false면 활성화+
let page = 1; // 1. 데이터를 가져올 페이지를 나타내는 변수를 선언한다.

document.getElementById('more').addEventListener('click', function() {
    // 2. fetch 함수를 사용하여 해당 URL에서 데이터를 가져온다. 
    // 2-1. URL에는 ${page}를 사용하여 페이지 번호를 동적으로 설정한다.
    fetch(`https://codingapple1.github.io/js/more${page}.json`)
    .then(res => res.json()) // fetch의 응답을 JSON 형식으로 파싱
    .then(data => { // JSON 데이터를 받아 처리
    
    	// 3. 데이터가 있는지 확인한다.
    	// 3-1. 가져올 데이터가 있는 경우
        if (data.length > 0) { 

            // (1) 가져온 데이터 배열을 순회하면서 각 항목마다 HTML 생성한다.
            data.forEach(item => {
                let html = `
                <div class="col-sm-4">
                    <img src="https://via.placeholder.com/600" class="w-100">
                    <h5>${item.title}</h5> 
                    <p>가격 : ${item.price}</p>
                </div>`;
               
                // (2) HTML 요소에 데이터를 추가한 HTML을 추가한다.
                document.querySelector('.row').insertAdjacentHTML('beforeend', html);
            });

	    // (3) 다음에 가져올 페이지를 설정하기 위해 페이지 번호를 증가시킨다.
            page++; 
            
        // 3-2. 가져올 데이터가 없는 경우
        } else {
        	// (1) 더보기 버튼을 비활성화한다.
            document.getElementById('more').disabled = true; 
        }
    })
    // 2-2. 오류가 발생하면 콘솔에 오류를 기록
    .catch(error => { 
        console.log(error);
    });
});

 

 

 

 

 

 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <!-- Bootstrap CSS -->
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
      rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"/>
  </head>
  <body>
    
    <div class="container">
      <div class="row">
      </div>
    </div> 
    
    <div class="container">
      <button class="btn btn-danger" id="more">더보기</button>
    </div>

    <script src="index.js"></script>
  </body>
</html>

 

 

 

index.js

var products = [
    { id : 0, price : 80000, title : 'Blossom Dress' },
    { id : 1, price : 50000, title : 'Spring Shirt' },
    { id : 2, price : 60000, title : 'Black pants' }
];

// 데이터만큼 상품 목록 만들기 (js로 html 생성하기)
// 1. 카드 레이아웃 3개 생성
// 2. 카드에 데이터 넣기
products.forEach((a, i) => {
    var a = 
        `<div class="col-sm-4">
            <img src="https://via.placeholder.com/600" class="w-100">
            <h5>${products[i].title}</h5> 
            <p>가격 : ${products[i].price}</p>
         </div>`;

        //     <h5>${a.title}</h5> 
        //     <p>가격 : ${a.price}</p>

    document.querySelector('.row').insertAdjacentHTML('beforeend', a);
});


// 상품 더보기 버튼
let page = 1; //데이터를 가져올 페이지를 나타내는 변수

document.getElementById('more').addEventListener('click', function() {
    // fetch 함수를 사용하여 해당 URL에서 데이터를 가져온다. 
    // URL에는 ${page}를 사용하여 페이지 번호를 동적으로 설정
    fetch(`https://codingapple1.github.io/js/more${page}.json`)
    .then(res => res.json()) // fetch의 응답을 JSON 형식으로 파싱
    .then(data => { // JSON 데이터를 받아 처리
        if (data.length > 0) { // 가져올 데이터가 있는 경우

            // 가져온 데이터 배열을 순회하면서 각 항목마다 HTML 생성
            data.forEach(item => {
                let html = `
                <div class="col-sm-4">
                    <img src="https://via.placeholder.com/600" class="w-100">
                    <h5>${item.title}</h5> 
                    <p>가격 : ${item.price}</p>
                </div>`;
                // 화면에 데이터를 추가한 HTML을 추가한다.
                document.querySelector('.row').insertAdjacentHTML('beforeend', html);
            });

            page++; // 다음에 가져올 페이지를 설정하기 위해 페이지 번호를 증가
        
        } else { // 가져올 데이터가 없는 경우
            document.getElementById('more').disabled = true; // 더보기 버튼을 비활성화한다.
        }
    })
    .catch(error => { // 오류가 발생하면 콘솔에 오류를 기록
        console.log(error);
    });
});

 

 

 


 

 

깃허브

https://github.com/kwonboryong/CodingApple/tree/main/ajax

 

 


 

 

출처

코딩애플

https://cocobi.tistory.com/121
https://www.daleseo.com/js-window-fetch/
https://yeri-kim.github.io/posts/fetch/