Fetch API는 네트워크 통신을 포함하여 리소스(데이터) 취득을 위한 인터페이스가 정의되어 있다.
Built-in API(자바스크립트 내장 라이브러리)로 별도의 설치 없이 모던 브라우저에서 사용이 가능하다. window Object(객체)에 속해있기 때문에 window.fetch()로 사용되기도 한다.
기존 XMLHttpHttps(XHR)를 대체하는 개념으로 Request / Response를 포함하며, 결과 값으로 Promise 객체를 반환한다. 때문에 XHR에서 Response를 확인하기 위해서 callback이나 event를 사용하던 부분을 .then()
, catch()
를 사용해서 확인한다.
let promise = fetch(URL, [option]);
//Get방식
fetch('http://example.com/movies.json') //서버 주소를 첫 번째 인자로 넘김
.then(res => console.log(res)) //통신 성공 시 수행 할 코드
.catch(err => console.log(err)); //error 발생 시 예외처리 할 코드
//Post방식
const option = {
method : "POST",
body : ...,
header : {}
}
fetch('http://example.com/movies.json', option) //두 번째 인자에 객체를 인자로 전달한다
.then(res => console.log(res)) //통신 성공 시 수행 할 코드
.catch(err => console.log(err)); //error 발생 시 예외처리 할 코드
첫 번째 인자로 URL, 두 번째 인자로 options 객체를 받고, Promise 객체를 반환한다.
반환된 객체는 API 호출이 성공했을 경우 응답(response) 객체를 resolve하고, 실패했을 경우에는 예외(error) 객체를 reject한다.
응답(Response)객체로부터는 HTTP응답 상태(status), HTTP응답 헤더(headers), HTTP응답 전문(body) 등을 읽어올 수 있다.
let myHeaders = new Headers();
와 같이 new Headers()(생성자 함수) 생성자를 사용해서 헤더 객체를 생성할 수 있다.// 1. set(), append() 메소드를 사용하여 property를 추가
let myHeaders = new Headers();
myHeaders.append("Content-Length", "Hello World".length.toString());
myHeaders.set("Content-Type", "text/plain"); //기존의 동일한 Property가 존재해도, 덮어쓸 수 있다.
// 2. 생성자에 인자로 전달
myHeaders = new Headers({
"Content-Type" : "text/plain",
"Content-Length" : "Hello World".length.toString()
})
// 3. has(), get(), getAll() 메소드로 value 확인하기
myHeaders.has("Content-Type"); // true
myHedaers.has("Set-Cookie"); // false
myHeaders.get("Content-Length"); // 11
myHeaders.append("X-Custom-Header", "AnotherValue");
myHeaders.getAll("X-Custom-Header") // ["ProcessThisImmediately", "AnotherValue"]
//4. delete()로 삭제
myHeaders.delete("X-Custom-Header");
Request, Response 의 body를 나타내는 객체이며, Content-Type과 그것이 어떻게 처리되어야 할 지를 정의할 수 있도록 하는 인터페이스
body는 아래에 기술한 타입들 중 하나의 인스턴스이다.
let form = new FormData(document.getElementByID('login-form'));
fetch('/login', {
method:'POST',
body: form
}
//Request(URL, [option])
//URL : 서버 주소
//option : method, headers, body... etc fetch의 두 번째 인자를 대체
const req = new Request("/api/posts", {
method: "GET",
headers: new Headers({ //Headers 인터페이스 사용 or 직접 객체입력
"content-type": "application/json",
}),
body: {
//Body 인터페이스로 대체 가능
name: "LeeHanur",
}
});
fetch(req)
.then(res => console.log(res))
.catch(err => console.log(err);
.then()
에서 .then((response) => {let data=response.json()})
과 같은 코드를 통해 응답 데이터를 json형태로 변환하는데, 이게 response가 아닐까 싶다.// Response 상수
Response.status // HTTP status의 정수치, 기본값 200
Response.statusText // HTTP status 코드의 메서드와 일치하는 문자열, 기본값 "OK"
Response.ok // HTTP status 코드가 200 ~ 299 값 인지에 대하여 Boolean으로 반환한다.
var myResponse = new Response(body, [init]);
// body: null 허용, Blob|BurfferSourse ... etc 응답된 body 의 typedmf wjddml
// init: status, statusText, headers 3가지 property 설정 가능
var myBlob = new Blob();
var init = {"status": 200, "statusText": "SuperSmashingGreat!"}
var myResponse = new Response(myBlob, init);
fetch()
메소드는 리소스(데이터)에 대한 요청(request)을 보내고, 응답(response)을 받으면 이를 fullfilled(성공)된 상태의 Promise에 담아 다시 return 시키는 역할을 한다.
fetch()
메소드가 리턴하는 Promise는 HTTP에러(예: 404에러)에 대해서는 reject되지 않으며, 오직 네트워크 요청 실패에 대해서만 reject된다. HTTP 에러에 대해서는 ok상태가 false인 resolve가 반환된다.
HTTP 에러를 확인하려면 .then()
을 이용해서 확인한다 .then(response => if(response.status === '404'){//...}
fetch()
의 첫번째 인자로는 요청할 대상 resource를 반드시 전달해줘야 한다. 이 resource는 URL과 같은 주소도 가능하고, 따로 생성한 Request 객체를 전달하는 것도 가능하다.
원격 API에 있는 데이터(리소스)를 가져올 때 쓰이는 GET 방식의 HTTP 통신으로, 단순히 특정 API에 저장된 데이터를 보여주는 웹페이지나 애플리케이션에서는 GET 방식의 HTTP 통신으로 충분하다.
fetch(url, [options]
에서 options에 아무것도 넘기지 않으면, 요청은 GET메서드로 진행되어 url로부터 콘텐츠(데이터)가 다운로드 된다.
대부분의 REST API들은 JSON 형태의 데이터를 응답하기 때문에, 응답(response)객체는 json() 메서드를 제공한다.
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
<!--
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit↵suscipit recusandae consequuntur …strum rerum est autem sunt rem eveniet architecto"
}
-->
원격 API에서 관리하고 있는 데이터를 생성해야 한다면 POST 방식의 HTTP 통신이 필요하다.
method
옵션을 POST
로 지정해주고, headers
옵션을 통해 JSON 포멧을 사용한다고 알려줘야 하며, request 전문을 JSON
포멧으로 직렬화하여 가장 중요한 body
옵션에 설정해준다.
method
: HTTP 메서드(GET, POST, PUT, DELETE...)body
: 요청 본문으로 다음 항목 중 하나여야 한다.대부분은 JSON을 요청 본문에 실어서 보낸다.
let user = {
name: 'oh',
subNamd: 'Minyoung'
}
fetch('/article/fetch/post/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringfy(user)
}).then((response) => console.log(response))
// Response {type: "cors", url: "https://jsonplaceholder.typicode.com/posts", redirected: false, status: 201, ok: true, …}
// json() 메서드 호출시, 응답 전문을 객체 형태로 얻을 수 있다.
fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Test",
body: "I am testing!",
userId: 1,
}),
})
.then((response) => response.json())
.then((data) => console.log(data));
// {title: "Test", body: "I am testing!", userId: 1, id: 101}
GET과 POST 만큼은 아니지만, 원격 API에서 관리하는 데이터의 수정과 삭제를 위해서 PUT과 DELETE 방식의 HTTP 호출을 사용할 때가 있다.
PUT방식은 method
옵션만 PUT
으로 설정한다는 점 빼놓고는 POST 방식과 매우 흡사하다.
DELETE방식은 보낼 데이터가 없고, 삭제만 하기 때문에 headers
와 body
옵션이 필요가 없다.
fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "DELETE",
})
.then((response) => response.json())
.then((data) => console.log(data));
//{}