[javascript] 더 간편한 프로미스(Promise)를 위한 패치(Fetch)
프로미스(Promise) 기반의 AJAX 즉, 비동기 통신을 프로미스 기반으로 간편하게 사용할 수 있도록 구현한 메서드가 패치(Fetch) 입니다.
기존 XMLHttpRequest 객체를 이용하는 AJAX와 기술적으로는 동일합니다.
일종의 프로미스용 래퍼(Wrapper) 라고 이해하면 쉽습니다.
사용 구문이나 구조가 XMLHttpRequest 보다 간단하기 때문에 프로미스를 비동기 통신에 사용하고 있다면, 패치를 이용하는 것을 추천합니다.
!주의할 점
프로미스와 마찬가지로 패치 또한 인터넷 익스플로러에서는 지원되지 않습니다.
패치 지원 여부를 확인해 패치를 사용할지 XMLHttpRequest 객체를 사용할지 구분하려면
if(windows.fetch) {}
와 같이 윈도우 전역 객체로 패치가 있는지 확인해서 분기 처리를 하면 됩니다.
프로미스를 사용해도 결국 비동기 통신을 통한 요청을 보내는 과정은 XMLHttpRequest를 사용해야 합니다.
XMLHttpRequest 객체를 생성하고 포트를 연 후 요청을 보내는 과정을 결국 동일하고, 응답에 대한 처리 과정을 프로미스가 담당합니다.
패치(Fetch)는 프로미스 객체 인스턴스를 반환합니다.
프로미스 객체 인스턴스를 생성할 필요 없이 패치로 비동기 요청을 보내면 프로미스 인스턴스가 반환됩니다.
패치의 가상 구문 예를 하나 들어보겠습니다.
fetch('https://request.com/api/data.json').then((response)=>{ console.log(response);}).catch((err)=>{ console.log(err);});
프로미스 객체를 생성하면서 비동기 요청 코드를 작성할 필요 없이, 요청을 패치(Fetch) 메서드로 보내면 생성된 프로미스 객체 인스턴스가 반환되면서 이행 완료 상태인 경우 then()을 호출합니다.
패치는 중요한 특징이 있습니다.
비동기 요청이 완료되지 못한 경우에만 거부 상태가 반환되고 catch()가 호출됩니다.
그 이외의 모든 경우는 이행 완료로 처리되어 then()을 호출합니다. HTTP 상태가 에러(500), 페이지 없음(404) 에러도 모두 이행이 완료된 것으로 간주하며, then() 콜백 함수 안에서 상태를 확인해 그에 맞는 처리를 별도로 해야 합니다.
패치 요청(Request) 옵션 적용
패치 메서드는 AJAX 요청 옵션과 같은 수준의 옵션 기능을 제공합니다.
옵션 사용 방법은 다음과 같습니다.
fetch(url, {method: 'GET', cache: 'no-cache'}).then(res=>{console.log(res)});
패치 요청의 옵션 설정은 두번째 파라메터에 옵션 객체를 인자로 전달하며 사용 가능한 패치 요청 옵션은 다음과 같습니다.
옵션 |
사용 가능 값 |
기본값 |
method |
GET, POST, PUT, DELETE |
GET |
mode |
cors, no-cors, same-origin |
same-origin |
cache |
default, no-cache, reloadd, force-cache, only-if-cached |
default |
credentials |
same-origin, omit, include * 자격증명에 필요한 인증서를 보내려면 'include' 를 사용하고, 자격 증명을 배제하려면 'omit'을 사용합니다. |
same-origin |
headers |
'Content-Type': 으로 적용 application/json, application/x-www-form-urlencoded, text/plain |
text/plain |
redirect |
follow, manual, error |
follow |
referrer | client, no-referrer | client |
body | BLOB, JSON, 텍스트, 폼데이터, 버퍼배열 타입의 문자열, 또는 객체 | "headers" 옵션에 Content-Type 을 적용한 경우 같은 타입의 데이터여야 함. 예를들어 JSON은 객체로 보낼 수도 있지만, headers 옵션에서 "text/plain" 으로 지정한 경우 JSON.stringify(data) 메서드로 문자열로 변환해서 적용해야 합니다. |
body 속성 값에는 요청, 또는 응답시 필요한 데이터가 들어갑니다.
HTML 폼에서 작성한 내용을 자바스크립트를 이용해 원격 서버에 저장하는 방법을 프로미스 패치로 구현하면 다음과 같습니다.
fetch(saveurl, { method: 'POST', mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, redirect: 'follow', referrer: 'no-referrer', body: new FormData(document.getElementById('myform'))}).then(response => console.log(response));
패치로 파일 업로드
HTML 폼의 파일 필드에서 선택한 파일을 폼 객체 인스턴트와 패치를 이용해 업로드 할 수 있습니다.
"body" 옵션에는 문자열 데이터 또는 객체를 붙일 수 있기 때문에, 폼 객체를 생성해 파일을 업로드합니다.
var fobj = new FormData();// 폼 인스턴스 생성var file = document.querySelector('input[type="file"]');//업로드할 파일 정보 얻기
fobj.append('photo', file.files[0]); //파일데이터 폼 인스턴스에 넣기
fetch('https://request.com/bb/upload', { method: 'POST', body: fobj}).then(response => console.log(response + ' saved!')).catch(error => console.log(error));