우리가 XMLHttpRequest보다 fetch를 선호하는 이유

DH.J·2024년 11월 3일
0

Javascript

목록 보기
8/8

What you will learn today

  • fetch 함수의 개념
  • fetch error처리 하는 방법
  • HTTP 요청 메서드
  • fetch와 XMLHttpRequest 비교

✔ fetch 함수란?

HTTP 파이프라인을 구성하는 요청과 응답 등의 요소를 JavaScript에서 접근하고 조작할 수 있는 인터페이스를 제공합니다

fetch 함수에는 HTTP요청을 전송할 URLHTTP요청 메서드, HTTP요청 header, payload 등을 설정한 객체를 전달합니다.

// fetch
fetch('https://jsonplaceholder.typicode.com/todos/1')
	.then(res => console.log(res));

이렇게 fetch 함수는 HTTP응답을 나타내는 Response 객체를 래핑한 Promise객체를 반환합니다.

// fetch함수가 반환한 Response 객체
Response {
  status: 200,
  statusText: 'OK',
  headers: Headers {...},
  body: (...),
  bodyUsed: false,
  ok: true,
  redirected: false,
  type: 'basic',
  url: 'https://jsonplaceholder.typicode.com/todos/1'
}

이때, Response 객체 역시 JSON 응답 본문을 그대로 포함하지는 않습니다.
Response는 HTTP 응답 전체를 나타내는 객체로, JSON 본문 콘텐츠를 추출하기 위해서는 json() 메서드를 호출해야 합니다.
json()은 응답 본문 텍스트를 JSON으로 파싱한 결과로 이행하는, 또 다른 프로미스를 반환합니다.

json()함수를 이용한 예시를 봅시다.

fetch('https://jsonplaceholder.typicode.com/todos/1')
	.then(res => res.json()) // res는 http응답 나타낸 response객체이다
	.then(json => console.log((json)));
{ userId: 1, id: 1, title: 'delectus aut autem', completed: false }

뭔가 이상하지 않나요?
JSON이 출력될 것을 기대했지만 javascript 객체가 출력이 되었어요.

json()함수는 이름과는 다르게 JSON을 입력으로 받아와서 파싱한 객체라는 점을 명심하자!


✔ error 처리에 주의하기

fetch('https://jsonplaceholder.typicode.com/xxx')
	.then(() => console.log('ok'))
	.catch(() => console.error('error'))

다음 코드의 결과를 예측해 봅시다.
error가 출력될 것 같지만 ok가 출력됩니다.

fetch함수가 반환하는 프로미스는 404 not found500 internal server error같은 HTTP error 상태 코드가 아니라, 오직 네트워크 에러 혹은 CORS 에러에 의해 요청이 완료되지 못한 상태에만 reject합니다.

Response {
  status: 404,
  statusText: 'Not Found',
  headers: Headers {...},
  body: (...),
  bodyUsed: false,
  ok: false,
  redirected: false,
  type: 'basic',
  url: 'https://jsonplaceholder.typicode.com/xxx'
}

따라서 우리는 fetch함수가 반환한 프로미스가 resolve한 불리언 타입의 ok상태를 확인해 명시적으로 에러를 처리할 필요가 있습니다.

// wrong url

fetch('https://jsonplaceholder.typicode.com/xxx/1')
	.then((res) => {
		if (!res.ok) throw new Error(res.statusText); // error 처리!
		return res.json();
	})
	.then(todo => console.log(todo))
	.catch(err => console.error(err));

이렇게 에러를 확인!

Error: Not Found
    at /workspace/start_node_js/app.js:4:22
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

✔ GET, POST, PATCH, DELETE 요청하기

1. GET

단순히 원격 API에 있는 데이터를 가져올 때 사용합니다.
또한 옵션 인자가 필요 없습니다.

// get
fetch('https://jsonplaceholder.typicode.com/todos/1')
	.then(res => res.json()) // res는 http응답 나타낸 response객체이다
	.then(json => console.log((json)));
// console
{ userId: 1, id: 1, title: 'delectus aut autem', completed: false }

2. POST

POST는 많은 양의 데이터를 보낼 때 사용합니다.
또한 비밀번호 같은 개인정보를 보낼 때 사용하기도 합니다.

두번째 인자 payload로 option객체가 들어옵니다.
option 객체 내부에는 method, headers, body가 포함됩니다.

// post
fetch('https://jsonplaceholder.typicode.com/todos', {
	method: 'POST',
	headers: {
		'content-Type': 'application/json'
	},
  	body: JSON.stringify({
		userId: 1,
		title: "new todo",
		completed: false
	}),
	
}).then((res) => {
	if (!res.ok) throw new Error(res.statusText);
	return res.json();
	})
	.then(todo => console.log(todo))
	.catch(err => console.error(err));
	
  1. method : method 옵션을 POST로 지정해 줍니다.

  2. headers : 데이터가 어떤 형식인지 서버에게 알려주는 부분입니다.
    그러므로 우리는 서버에게 JSON format을 사용한다고 알려줘야 합니다.

  3. body : 전송할 데이터에 해당하는 중요한 부분입니다.
    JSON.stringify()로 서버로 보낼 데이터가 JSON 포맷임을 알려주지 않으면 Error: Internal Server Error가 발생합니다.

3. PUT

존재하는 자원을 변경할 때 사용합니다.
method 옵션을 PUT으로 변경하는 것 제외하곤 POST와 동일합니다.

4. DELETE

존재하는 자원을 삭제할 때 사용합니다.
보낼 데이터가 없으므로 headers와 body를 생략합니다.

fetch('https://jsonplaceholder.typicode.com/todos/1', {
	method: 'DELETE',	
}).then((res) => {
	if (!res.ok) throw new Error(res.statusText);
	return res.json();
	})
	.then(todo => console.log(todo))
	.catch(err => console.error(err));

✔ 우리가 XMLHttpRequest보다 fetch를 선호하는 이유

지금까지 javascript를 배워왔다면 fetch는 http 요청 전송 기능을 제공한다는 것을 알고 있을 것입니다.
그런데 왜 fetchXMLHttpRequest 객체보다 더 자주 쓰는지 생각해 보셨나요?

1. 사용법이 간단하다.

2. promise를 지원한다.

3. 대부분의 브라우저에서 지원한다.

일부 브라우저는 XMLHttpRequest를 지원하지 않습니다.

Reference

  1. https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch
  2. https://velog.io/@eunjin/JavaScript-fetch-%ED%95%A8%EC%88%98-%EC%93%B0%EB%8A%94-%EB%B2%95-fetch-%ED%95%A8%EC%88%98%EB%A1%9C-HTTP-%EC%9A%94%EC%B2%AD%ED%95%98%EB%8A%94-%EB%B2%95
  3. https://www.daleseo.com/js-window-fetch/
profile
평생 질문하며 살고 싶습니다.

0개의 댓글