티스토리 뷰

1. fetch를 사용한 이유

jquery ajax를 사용하지 않고(바닐라 자바스크립트 지향) 비동기 호출을 할 수 있는 방법을 찾던 중, 원시적인 XMLHttpRequest를 사용하는 방법과 fetch API를 사용하는 방법 대략 두 가지가 있음을 알게 되었다. XMLHttpRequest의 경우 브라우저별로 객체 생성을 달리해야 하는 번거로움이 있다. 그래서 나온 게 ajax. 그러나 난 jquery를 기반으로 하는 ajax를 쓰고 싶지 않다! 고로 XMLHttpRequest에 비해 브라우저 호환성 걱정할 필요없고 사용법도 간단한 fetch를 선택했다.

아래는 실제 프로젝트에 사용한 예제다.

 

 

2. 예제

/**
 * 비동기 호출 함수 (POST-일반)
 * @param {string} url 비동기 호출할 주소
 * @param {object} params 매개변수
 * @param {method} callbackMethod 실행될 함수
 */
function apiFetchPost(url, params, callbackMethod) {
    fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "X-Requested-With": "XMLHttpRequest"
        },
        body: new URLSearchParams(params)
    })
    .then(res =>{
        if (res.redirected) { // 리다이렉트가 있을 경우 (에러 발생 시 화면 이동을 위해)
            window.location.href = res.url;
            res.redirect(res.url)
        }
        // 응답 데이터를 JSON 형태로 받아서 다음 then으로 넘김
        return res.json()
    })
    .then(res => {
        callbackMethod(res); // 함수 실행
    })
    .catch((error) => {
        console.log(error);
        alert("에러가 발생했습니다. \r\n관리자에게 문의해주십시오.");
    });
}

/**
 * 비동기 호출 함수 (POST-파일)
 * @param {string} url 비동기 호출할 주소
 * @param {object} params 매개변수
 * @param {method} callbackMethod 실행될 함수
 */
function apiFetchFile(url, params, callbackMethod) {
    fetch(url, {
        method: "POST",
        headers: {"X-Requested-With": "XMLHttpRequest"},
        body: params
    })
    .then(res =>{
        if (res.redirected) { // 리다이렉트가 있을 경우 (에러 발생 시 화면 이동을 위해)
            window.location.href = res.url;
            res.redirect(res.url)
        }
        // 응답 데이터를 JSON 형태로 받아서 다음 then으로 넘김
        return res.json()
    })
    .then(res => {
        callbackMethod(res); // 함수 실행
    })
    .catch((error) => {
        console.log(error);
        alert("에러가 발생했습니다. \r\n관리자에게 문의해주십시오.");
    });
}

 

위 함수를 사용할 땐 아래와 같이 사용한다.

 

let params = {
  whoAreYou: "호랑이"
  , addr: "숲속 1번지"
  , favorite: "토끼"
}

apiFetchPost("/member/join", params, function(resData) {
  console.log("자 응답 데이터가 찍힐 것입니다.");
  console.log(resData);
});
let formData = new FormData();
// 파일 외의 데이터 같이 넘겨줄 때.
formData.append("userNm", document.getElementById("userNm").value); // 이렇게 일일히 넣어도 되고.

// let formElement = document.getElementById("formId");
// let formData = new FormData(formElement); // 이렇게 한방에 넣어도 되고.

// 파일 여러 개 넘길 때.
let profileFiles = document.getElementById("profileFiles").files;
for (let i = 0; i < profileFiles.length; i++) {
	formData.append("files", profileFiles[i], profileFiles[i].name);
	// formData.append("fileNm"+ i, profileFilesInput[i].name);
}

apiFetchFile("/file/fileUpload", formData, function(resData) {
  console.log("자 응답 데이터 불러와봅시다.");
  console.log(resData);
});

 

컨트롤러 단은 아래와 같다.

@RequestMapping("/member/join")
@ResponseBody
public JSONObject memberJoin(@RequestParam HashMap<String, Object> params) throws Exception {
  String whoAreYou = (String) params.get("whoAreYou");
  String addr = (String) params.get("addr");
  String favorite = (String) params.get("favorite");

  // 쿵짝쿵짝.... 

  HashMap<String, Object> resultMap = new HashMap<String, Object>();
  resultMap.put("msg", "SUCCESS");
  resultMap.put("data", "이것은 응답 데이터입니다!");
  JSONObject result = new JSONObject(resultMap);

  return result;
}

@RequestMapping("/file/fileUpload")
@ResponseBody
public JSONObject fileUpload(@RequestParam List<MultipartFile> files, @RequestParam String userNm) throws Exception {
  // 쿵짝쿵짝....

  HashMap<String, Object> resultMap = new HashMap<String, Object>();
  resultMap.put("msg", "SUCCESS");
  JSONObject result = new JSONObject(resultMap);

  return result;
}

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함