프로그래밍/JavaScript

[JS] 파일과 데이터를 모두 body에 넣어 API 요청하기 | form 태그 활용기 (2)

choar 2022. 8. 30. 00:13
반응형

 

[JS] 파일과 데이터를 모두 body에 넣어 API 요청하기 | form 태그 활용기 (2)

React로 쇼핑몰 프로젝트를 짜다가 파일(이미지)과 데이터(문자열, 숫자)를 모두 body에 넣어 API를 요청해야 하는 경우가 생겼다.

상품 판매자가 상품을 등록할 때 위와 같은 기능이 필요했다.

상품 등록 페이지

React에서 바로 하려니 어려워서, (1) pure HTML로 먼저 짜보고 (2) pure HTML+JavaScript로 짜보고 (3) React에 적용하는 과정을 거쳤다.

HTML form 태그에 대해 잘 몰랐는데, pure HTML로 먼저 짜보면서 HTML form을 구성하는 방법에 대해서 공부할 수 있었다.

pure HTML로 짠 내용은 이전 포스팅을 참고하시면 된다.

 

[HTML] 파일과 데이터를 모두 body에 넣어 API 요청하기 | form 태그 활용기 (1)

[HTML] 파일과 데이터를 모두 body에 넣어 API 요청하기 | form 태그 활용기 (1) React로 쇼핑몰 프로젝트를 짜다가 파일(이미지)과 데이터(문자열, 숫자)를 모두 body에 넣어 API를 요청해야 하는 경우가

choar816.tistory.com

 

JavaScript를 더해서 짠 코드의 index.html 코드는 다음과 같다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        label {
            display: inline-block;
            width: 100px;
        }
    </style>
    <title>Document</title>
</head>
<body>
    <form>
        <p>
            <label for="image">image</label>
            <input id="image" name="image" type="file" >
        </p>
        <p>
            <label for="product_name">product_name</label>
            <input id="product_name" name="product_name" />
        </p>
        <p>
            <label for="price">price</label>
            <input id="price" name="price" />
        </p>
        <fieldset>
            <legend>shipping_method</legend>
            <div>
                <input type="radio" id="delivery" name="shipping_method" value="DELIVERY" checked />
                <label for="delivery">택배</label>
            </div>
            <div>
                <input type="radio" id="parcel" name="shipping_method" value="PARCEL"/>
                <label for="parcel">직접</label>
            </div>
        </fieldset>
        <p>
            <label for="shipping_fee">shipping_fee</label>
            <input id="shipping_fee" name="shipping_fee" />
        </p>
        <p>
            <label for="stock">stock</label>
            <input id="stock" name="stock" />
        </p>
        <p>
            <label for="product_info">product_info</label>
            <input id="product_info" name="product_info" />
        </p>
        <input type="hidden" name="token" value="you should directly add token value here" />
        <input type="submit" id="submit" />
    </form>
    <script src="script.js"></script>
</body>
</html>

변한 건 다음과 같다.

  • form 태그의 프로퍼티 제거
  • script 태그 추가

 

script.js 코드는 다음과 같다.

// form 요소를 가져온다.
const form = document.querySelector("form");

// 버튼을 눌렀을 때 콜백함수가 실행되도록 한다.
form.addEventListener("submit", (e) => {
  // submit 버튼을 눌렀을 때 reload되지 않도록 한다.
  e.preventDefault();
  // FormData 객체를 만들고, form 요소를 전달한다.
  const data = new FormData(form);

  // URL에 요청을 보낸다.
  fetch("https://url_to_make_request/", {
    method: "POST",
    headers: {
      // localStorage에 token이 저장된 경우, 다음과 같이 사용할 수 있다.
      Authorization: `JWT ${localStorage.getItem("token")}`,
    },
    // body로 FormData 객체를 전달해준다.
    body: data,
  })
    .then((res) => res.json())
    .then((data) => console.log(data))
    .catch((err) => console.log(err));
});

위와 같이 form 요소를 그대로 전달해 FormData로 만들려면 form 태그에 name 속성이 잘 들어가 있어야 한다.

자바스크립트를 사용하면 Authorization header도 추가할 수 있다.

URL, token 등은 적절히 수정하면 된다.

 

form (HTML+JS)

위와 같이 form 내용을 채우고 Submit 버튼을 눌렀더니 원하는 대로 상품이 잘 등록된 것을 확인할 수 있었다.

submit 전후

 

🌟 전체 코드 GitHub 주소

https://github.com/choar816/form-html-js

https://choar816.github.io/form-html-js/


References

https://developer.mozilla.org/ko/docs/Learn/Forms/How_to_structure_a_web_form

https://developer.mozilla.org/ko/docs/Web/API/FormData/FormData

반응형