(Ajax) Fetch API

호두파파·2021년 4월 21일
0

Node.js

목록 보기
5/25

Fetch는 네트워크 요청/응답에 관련된 일반적인 Request/Response Object를 제공한다. 이 말은 범용성이 좋다는 말이다. 캐시, 웹 서비스 핸들링 등 Response를 프로그래밍 언어로 조작하는 모든 것을 허용한다는 뜻이다. 또한 CORS, HTTP Origin header semantics와 같은 개념들도 정의해놨고 이걸들을 따로 수정할 수 있다.

.fetch()메소드를 사용하면 요청과 응답을 만들 수 있다.
fetch()는 거의 모든 상황에서 ajax 통신을 가능하게 한다.

.fetch()는 2개의 매개변수를 받는데 첫번째는 URL이고 두번째는 Option이다. URL은 필수 매개변수이다. 그리고 이 녀석은 ajax통신이 성공하든 실패하든 response로 분해할 수 있는 Promise를 리턴한다.

Fetch interfaces

fetch에는 4가지의 인터페이스와 1가지의 메소드 밖에 없다.

Body

mixin 타입이라고 한다. Request, Response 두개 모두에서 사용된다. 딱 한가지 속성을 가지고 있는데, Body.body, Body.bodyUsed 이다. Body에는 5가지의 메소드가 존재한다.

  • Body.arrayBuffer()
  • Body.blob()
  • Body.formData()
  • Body.json()
  • Body.text()

Headers

Request와 Response의 Headers instance를 생성할 수 있다.
let myHeaders = new Header();같이 생성할 수 있다. 생성한 Header에 속성들을 추가, 제거, 조회 할 수 있다. 다음과 같은 메소드를 제공한다.
append(), delete(), entries(), forEach, get(), has(), key(), values, getAll()

예제

var myHeaders = new Headers();

myHeaders.append('Content-Type', 'text/xml');
myHeaders.get('Content-Type') // should return 'text/xml'

var myHeaders = new Headers({
    'Content-Type': 'text/xml'
});

// or, using an array of arrays:
myHeaders = new Headers([
    ['Content-Type', 'text/xml']
]);

myHeaders.get('Content-Type') // should return 'text/xml'

Request

Request instance는 요청 headers의 properties를 포함한다.

const request = new Request('https://www.mozilla.org/favicon.ico');

const URL = request.url;
const method = request.method;
const credentials = request.credentials;

fetch(request)
  .then(response => response.blob())
  .then(blob => {
    image.src = URL.createObjectURL(blob);
  });

Response

fetch()는 Promise를 리턴하는데 Promise에서 값을 추출하면 Response를 얻을 수 있다.


USE Fetch

GET 요청하기

간단한 express 서버와 프론트의 ajax 통신을 살펴보자

express route 코드

/* GET home page. */
router.get('/', function (req, res, next) {
  res.render('index', { title: 'Hello, Fetch!' });
});

router.get('/title/:title', (req, res, next) => {
  res.json({ title: req.params.title });
})

index페이지

<h1 id="title">{{{title}}}</h1>
  <input id="input" type="text">
  <input type="button" value="submit" onclick="submit()">
  
  <script>
    let submit = () => {
      let input = document.getElementById('input');
      let tatget = document.getElementById('title');
      fetch('/title/' + input.value)
      	.then(res => res.join())
      	.then(json => target.innerHTML = json.title);
      }
    </script>

그리고 submit 버튼을 클릭하면 왼쪽에 입력값을 파라미터로 GET 통신을 진행한다. 통신에 성공하면 서버에서 body에 JSON을 담아서 반환하고 fetch는 promise를 통해 json의 값을 뽑아낸다.

fetch('/title/'+title)
		.then(res => res.join())
	.then(json => target.innerHTML = json.title);

아까 언급했듯이 fetch()는 Promise를 리턴한다. 첫번째 then에서 Response의 json을 return하고 다음 then에서 json의 값을 뽑아내서 Hello,Fetch! 에 해당하는 값을 반환한다.

Post 요청하기

  • express route 코드에 다음 코드를 추가하자
router.post('/title, (req, res, next) => {
  res.json({title: req.body.title});
})
  • 프론트의 코드도 다음과 같이 수정하자
let submit = () => {
      let input = document.getElementById('input');
  	  let target = document.getElementById('title');
  	  fetch('/title, {
        method: 'post',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ 'title': input.value }),
      })
      	.then(res => res.join())
		.then(json => target.innerHTML = json.title)
		.catch(error => console.error('Error: ', error));
}

fetch 에러처리와 비동기 요청

async / await

let submit = async () => {
      let input = document.getElementById('input');
      let target = document.getElementById('title');
      let replaceTitle = json => target.innerHTML = json.title;
      let url = '/title'
      let options = { 
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({'title': input.value}),
      }
      
      try {
        let response = await fetch(url, options);
        let json = await response.json();
        let task = await replaceTitle(json);
      } catch (err) {
        console.log(err);
      }
    }

fetch는 기본적으로 비동기로 동작하기 때문에 가끔 원하는대로 순서대로 동작하지 않을때가 있다. 그럴때 순서를 보장받기 위해서 async / await를 사용한다.
await는 async 선언이 된 함수 안에서만 사용이 가능하며 Promise값을 기다렸다가 Promise값에서 결과값을 추출해준다. 그리고 async를 선언한 함수는 반드시 Promise를 리턴한다. 이렇게 간단하게 순서를 보장받을 수 있기 때문에 디버깅, 예외처리가 용이해진다.

profile
안녕하세요 주니어 프론트엔드 개발자 양윤성입니다.

0개의 댓글