저번 시간에 XHR에 대하여 공부 및 실습을 해보았다. 그렇다면 이번에는 이후에 탄생한 fetch에 대하여 정리해보도록 하겠다. 우선 fetch가 생겨난 배경부터 설명해보겠다. 그동안 비동기 요청을 위해서는 XHR을 이용해야했다. 하지만 XHR객체를 이용해야하고, EVENT에 따라서 등록된 변경사항을 받아야 했고, 요청의 성공, 실패 여부나 상태에 따라 처리하는 로직이 보기 좋지 않았다고 한다. 이를 보완하기 위해 fetch가 생겨났고, 그 결과 http 요청에 최적화 할 수 있고 상태도 잘 추상화 되어있고, Promise를 기반으로 되어있기 때문에 추가 로직을 다루는대에 최적화 할 수 있게 되었다고 한다.
우선, 기본적인 사용 방법이다.
// https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Fetch%EC%9D%98_%EC%82%AC%EC%9A%A9%EB%B2%95
fetch('http://example.com/movies.json') // 경로로 요청 후에 Promise 반환
.then(function(response) {
return response.json(); // resolve를 실행시켜 서버로부터 받은 데이터를 json으로 파싱한다.
})
.then(function(myJson) {
console.log(JSON.stringify(myJson)); // 파싱된 json 데이터를 string 형태로 출력한다.
});
Promise를 이용하기 때문에, 상태 변경을 사용하는 XHR에 비해 동기화에 대해 편리하고 가시성도 좋음을 알 수 있다. fetch는 Promise를 반환하는데, 이어지는 .then을 통해 Promise가 실행된다. 그리고 나서 서버로부터 요청이 성공했든 실패했든 Response 객체를 얻게 된다. Response 객체는 Body의 인터페이스를 갖고 있기 때문에, 데이터의 타입에 따라 .json(), .blob(), .formData, .text() 등으로 파싱할 수 있다. 이를 통하여 페이지 정보를 갱신하던지 데이터를 다룰 수 있게 된다.
fetch를 사용하기 위해서는 두 가지 방법이 있다. 첫 번째로 직접적인 URL을 넣는 방법이 있다.
// https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Fetch%EC%9D%98_%EC%82%AC%EC%9A%A9%EB%B2%95
// Example POST method implementation:
postData('http://example.com/answer', {answer: 42})
.then(data => console.log(JSON.stringify(data))) // JSON-string from `response.json()` call
.catch(error => console.error(error));
function postData(url = '', data = {}) {
// Default options are marked with *
return fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // no-referrer, *client
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
.then(response => response.json()); // parses JSON response into native JavaScript objects
}
위의 예시에서 postData 함수 속의 fetch를 보면 첫 번째로는 url을, 두 번째 값으로는 요청을 위한 Header, Body 값들을 갖고 있는 객체가 들어감을 알 수 있다. 만약 필요가 없다면, 두 번째 인수에 대해서는 인자를 넣지 않아도 default 값이 있기 때문에 상관이 없이 실행이 된다. 이어져 얻게되는 response는 Body 인터페이스를 갖고 있기 때문에, json 형태로 파싱할 수 있었다.
다음으로 Request 객체를 이용하는 방법이 있다.
//https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Fetch%EC%9D%98_%EC%82%AC%EC%9A%A9%EB%B2%95
var myHeaders = new Headers();
var myInit = { method: 'GET',
// Headers 객체가 들어간다.
// {'Content-Type': 'application/x-www-form-urlencoded'}가 들어가도 괜찮다.
headers: myHeaders,
mode: 'cors',
cache: 'default' };
// myInit 값을 주지 않으면 default 값으로 생성된다.
var myRequest = new Request('flowers.jpg', myInit); // Request 객체 생성
fetch(myRequest).then(function(response) { // fetch의 인자로 Request 객체 하나만을 넣는다.
return response.blob();
}).then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
myImage.src = objectURL;
});
이번 예시에서는 Request 객체를 미리 생성한 뒤, fetch에 Request 객체 하나만을 넣어주었다. 하지만 MDN에 따르면, 권장하지 않는 방법이라고 한다.
배운 것들을 바탕으로 실습 코드를 작성해보았다.
//fetchServer.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.get('/', function (req, res) {
res.sendFile(__dirname + '/fetch.html');
});
app.post('/req', function (req, res) {
res.send(req.body)
});
server.listen(3000, function () {
console.log('서버가 시작되었습니다.');
});
<!--fetch.html-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title</title>
</head>
<body>
<script>
var req = function() {
var data = {
// 전송할 값을 추출한다.
data1: document.querySelector('#text1').value
}
fetch('http://localhost:3000/req', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
// 전송할 데이터를 json 인코딩해야 한다.
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
// 서버로부터 받은 값을 json 파싱하여 div 갱신함
document.querySelector('#responseData').innerHTML = result.data1;
});
// 데이터를 전송하고 전송 값으로 div 갱신함
document.querySelector('#requestData').innerHTML = data.data1;
}
</script>
<input type="text" id="text1" />
<button onclick="req()">fetch</button>
<div id="requestData">requestData</div>
<div id="responseData">responseData</div>
</body>
</html>
developer.mozilla.org/ko/docs/Web/API/Fetch_API
developer.mozilla.org/ko/docs/Web/API/Fetch_API/Fetch%EC%9D%98_%EC%82%AC%EC%9A%A9%EB%B2%95
developer.mozilla.org/ko/docs/Web/API/Fetch_API/Basic_concepts
developer.mozilla.org/ko/docs/Web/API/Request
developer.mozilla.org/ko/docs/Web/API/Response
developer.mozilla.org/ko/docs/Web/API/Body
medium.com/@kkak10/javascript-fetch-api-e26bfeaad9b6
'javascript' 카테고리의 다른 글
정규표현식으로 사이에 있는 내용 가져오기 (0) | 2023.02.12 |
---|---|
HTML 문서 렌더링 (0) | 2020.11.19 |
XMLHttpRequest (0) | 2020.11.10 |
Promise (0) | 2020.11.03 |
정리할 web api 목록 (0) | 2020.09.16 |