XMLHttpRequest객체를 이용해서 JavaScript에서 서버에 동기 또는 비동기식 요청을 보낼 수 있으며 요청에 대한 응답 정보를 웹페이지에서 로드할 수 있습니다. 따라서 웹페이지를 다시 로드하지 않아도 웹페이지의 일부만 변경할 수 있습니다.
1. XMLHttpRequest 객체를 생성합니다.
2. open()메서드로 요청에 필요한 정보를 설정합니다.
3. send()메서드로 서버에 요청을 보냅니다.
4. 응답에 대한 콜백 함수를 생성합니다.
다음 코드의 의미를 알아보아요.
// 1. XMLHttpRequest 객체를 생성합니다.
const requestObj = new XMLHttpRequest();
// 2. open()메서드로 요청에 필요한 정보를 설정합니다. 요청을 초기화하고, 통신방법과 요청을 발신할 대상의 주소를 전달합니다.
requestObj.open('GET', 'url');
// onreadystatechange 프로퍼티는 XMLHttpRequest 객체의 readyState 프로퍼티 값이 변할 때마다 자동으로 호출되는 함수입니다.
requestObj.onreadystatechange = () => { // readystate 가 변화하면 실행되는 이벤트리스너 입니다.
// readystate : 요청을 보내는 클라이언트의 상태를 의미합니다.
// readystate의 종류
// 0 (UNSENT) - XHR 객체가 생성되었지만 아직 초기화되지 않았습니다.
// 1 (OPENED) - open()함수가 호출되어 요청이 초기화되었습니다.
// 2 (HEADERS_RECEIVED) - send()함수가 호출되었습니다.
// 3 (LOADING) - 데이터를 다운받는 중 입니다.
// 4 (DONE) - 통신이 완료되었습니다.
// readyState 프로퍼티는 XMLHttpRequest 객체의 현재 상태입니다.
// requestObj.readyState === 4 : 데이터를 전부 받은 상태라는 의입니다.
// status는 서버의 문서 상태입니다.
// requestObj.status === 200 : 서버로부터 응답상태가 요청에 성공하였다는 의미입니다.
if (requestObj.readyState == 4 && requestObj.status == "200") {
// responseText : 서버에 요청하여 응답으로 받은 데이터를 문자열로 반환합니다.
const result = requestObj.responseText;
}
};
// 3. send()메서드로 서버에 요청을 보냅니다.send 메소드가 실행되어야만 우리가 위에서 설정한 내용들이 의미를 가지게 됩니다.
requestObj.send();
| 값(status) | 텍스트(statusText) | 설명 |
|---|---|---|
| 200 | OK | 요청 성공 |
| 403 | Forbidden | 접근 거부 |
| 404 | Not Found | 페이지 없음 |
| 500 | Internal Server Error | 서버 오류 발생 |
하지만 XMLHttpRequest API로 통신을 주고 받을 당시 큰 번거로움을 느끼고 JQuery를 통해 구현하기 시작하다가 이후 fetch API가 ES6표준으로 등장하면서 fetch API를 통해 통신하는것이 주요방식으로 자리를 잡았습니다.
XMLHttpRequest

fetch()

바로 XMLHttpRequest가 생성하는 인스턴스는 통신 기능을 수행하는 XMLHttpReques 객체를 반환하지만 Fetch API는 인스턴스를 만들지 않고 대신 Promise를 반환한다는 것입니다.
let result = fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json');
console.log(result);
원하는 url을 fetch() 인자로 넣어준 뒤 그 값을 json형태로 변환시켜 넘겨주면 이 값을 다룰 수 있게 됩니다.
XMLHttpRequest 객체보다 훨씬 간단한 방법으로 데이터를 가져오는데요.
fetch()는 기본적으로 다음과 같이
const promise = fetch(resource, [option])
fetch는 2개의 매개변수를 가집니다.
만약 두번째 매개변수를 입력하지 않는다면 default 값으로 GET메서드 데이터 요청이 전송됩니다.
또한 fetch()가 반환하는 promise는 네트워크 장애 및 요청 실패 시(서버가 개입되지 못한 경우)만 rejected 상태이고 나머지는 fullfilled 상태입니다.
만약 404, 500 등 오류를 수신하게 된다면 Response 객체의 ok 속성이 false가 되고 나머지 상황은 true가 된다.
그리고 Promise인 전달받은 Response 객체를 통해서 실제 데이터를 받을 수 있습니다.
응답 몸체에 담긴 데이터는 사용자가 원하는 형태로 파싱하여 접근할 수 있는데 여기에는 대표적으로 JSON 형태로 반환하는 response.json()과 텍스트 형태로 반환하는 response.text() 메서드들이 있습니다.
get 방식
const url = "https://jsonplaceholder.typicode.com/posts/1";
const byFetch = () => {
fetch(url1)
// 응답 처리 1단계: 상태만 파악 가능
.then.((response) => {
if(!response.ok) {
throw new Error(`오류 발생: ${response.status}`);
}
return response.json(); // 응답은 native js 객체로 변환
// 응답 처리 2단계 실제 데이터 활용
.then((json) => console.log(json))
.catch((error) => console.log.error("fetch fail",error));
fetch()를 활용하게 간단하게 코드를 만들어보았습니다.
class UserStorage {
// 유저가 등록되었는지 확인
searchUser(userName, password) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'users.json');
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
const result = JSON.parse(xhr.responseText).user.find((item) => {
return item.userName === userName && item.password === password
});
if (result) {
resolve(userName);
// onSuccess(userName);
} else {
reject('user not found');
// onError(new Error('user not found'));
}
}
}
xhr.send();
})
}