JS/ajax

[ajax] 비동기 처리 - Axios

개발메모장 2023. 10. 25. 15:52

CDN

// cdn
// <head></head> 안에 넣어주기
<head>
	<title>Title</title>
	<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>

 

기본 문법

function ajax1() {

	axios.request({
    	url: "url", 			// url 통신 주소
        method: "POST",			// GET, POST 방식 (기본값은 GET)
        params: { 			// 전송할 값 
		key: value
        },
    }).then(function (response){
    	// 응답 성공했을 때 then
        console.log(response);
    }).catch(function (error){
    	// 에러인 경우 실행
        console.log(error);
    }).finally(function (){
    	// 항상 실행
    })

}
function ajax1() {

	axios.request({
    	url: "/user", 			// url 통신 주소
        method: "POST",			// GET, POST 방식 (기본값은 GET)
        params: { 			// 전송할 값 (json형식 추천, reques, get 방식의 기본값은 쿼리스트링형식으로 넘어감)
		name: "gildong",	// axios.post, delete, put 등등 기본 값은 json
		age: 33,
		country: "korea"
        },
        
    })

}

만약 나는 json 형태가 아닌 쿼리스트링형식으로 하고 싶다면 ?

예시)

// /user?name=gildong&age=33&country=korea
// put, delete, post 방식은 기본 값이 json 형태로 데이터가 전송
// 쿼리스트링 형식으로 하고 싶다면 아래와 같이 headers의 content-type을 작성
function ajax1() {

	axios.put("/user",{
    		name: "son",
    		address: "korea"
	}, {
    		headers: {
        		"content-type": "application/x-www-form-urlencoded"
    		}
	});
}

 

요청 형태 문법 데이터 기본 전송 방식
POST (CREATE)  axios.post(url, data[, config])  JSON 
GET (READ)  axios.get(url[, config])  application/x-www-form-urlencoded
(쿼리 스트링 형식)
PUT (UPDATE) axios.put(url, data[, config])  JSON
DELETE (DELETE) axios.delete(url[, config]) JSON

then - 응답에 성공 했을 때 실행

then 은 응답데이터를 받은 후 실행됨.

<script>
        function ajax1(){
            axios.get("/user")
                .then(function (res) => { // 응답 받은 데이터를 파라미터(매개변수)에 넣어 사용
                   	
                    // 파싱되어 들어가진 상태이다.
                    // 속성값으로는 data, status, statusTest, headers, config 가 있다.
                    // 주로 사용하는건 data, status
                    console.log(res.data);		// 응답 받은 값을 추출, 파싱된 상태
                    console.log(res.status);		// Http 상태 코드
                    console.log(res.statusText);
                    console.log(res.headers);
                    console.log(res.config);

                })
        }
    </script>

 

예시)

응답 받은 데이터

// 이렇게 응답받은 데이터의 property명을 이용해 각각의 값을 추출할 수 있다.

<script>
    function ajax1(){
        axios.get("/user")
            .then((res)=>{
                console.log(res.data.city);
                console.log(res.data.price);
                console.log(res.data.list[0]);
                console.log(res.data.birth);
            })
    }
</script>

 

then 특징

1. then도 promise 객체를 return 하기 때문에 then이 끝난 후 또 then을 여러번 작성할 수 있다.

<script>
    function ajax1(){
        axios.get("/user")
            .then((res)=>{
                console.log("응답 완료 후 실행");
            })
            .then((res)=>{
            	// 순서대로 실행된다.
                console.log("그 다음 실행");
            })
            .then((res)=>{
            	// 위에서 아래로 순차적으로 실행
                console.log("또 그다음 실행")
            })
    }
</script>

 

2. then 함수의 파라미터(매개변수)의 값은 직전 함수의 return된 값이다.

<script>
    function ajax1(){
        axios.get("/user")
            .then((res)=>{ // axios.get에서 return된 값
                console.log("첫 함수");
                return res.data; 
            })
            .then((param)=>{ // 첫 then에서 return된 값 res.data
                console.log("두번째 함수");
                console.log(param); // res.data값 출력
                return 345;
            })
            .then((param)=>{ // 두번째 함수에서 return된 값 345
                console.log("세번째 함수");
                console.log(param); // 345 출력
            })

    }
</script>

 

3. 구조분해할당 형식으로 파라미터 받기 

// axios.get으로 응답받은 값의 프로퍼티가 price, birth, name, city등이 있었다면
<script>
    function ajax1(){
        axios.get("/user")
            .then(res => res.data)	// res.data로 값을 return
            .then(({price, birth, name, city}) => { // return받은 객체의 프로퍼티를 구조분해 할당{} 밖에 () 감싸줘야함
                console.log(price)
                console.log(birth)
                console.log(name)
                console.log(city)
            });
    }
</script>

구조분해할당 설명: https://fuckingjava.tistory.com/120

 

구조분해할당(destructuring assignment)

// 구조분해할당 // destructuring assignment // a 객체 let a = { name: "son", age: 30 }; // 기존의 객체의 값을 출력할 때 아래와 같은 방법으로 사용 console.log(a.name); console.log(a.age); // 또는 이렇게 할당해서 사

fuckingjava.tistory.com


catch - 에러 발생(응답 실패)시 실행

HTTP Status 상태 코드가 200번대(성공) 아니면 모두 실패로 간주함

실패하게되면 catch 파라미터는 error객체로 받아진다.

<script>
    function ajax1(){
        axios.get("/user")
            .catch((error) => console.log(error)) // error 객체로 받아짐
    }
</script>

파라미터명은 꼭 error로 할 필요는 없다.

<script>
    function ajax1(){
        axios.get("/user")
            .catch((e) => console.log(e)) // 꼭 error라는 파라미터명으로 안받아도됨
    }
</script>

콘솔에 찍힌 error 객체

 

error 객체에 있는 프로퍼티 값들을 사용해 error를 컨트롤할 수 있다.

예시)

<script>
    function ajax1(){
        axios.get("/user")
            .catch(function (error) {
            
		console.log(error.response.status); // 응답 상태 코드
                
                let status = error.response.status; // 응답 상태 코드를 status에 담고
                
                // 값에 따라서 출력
                if (status >= 400 && status < 500) {
                    console.log("요청이 잘못됐습니다.")
                } else if (status >= 500 && status < 599) {
                    console.log("서버에서 오류가 발생했습니다.")
                }

            });
    }
</script>

finally - 응답 성공, 실패 상관없이 무조건 실행

<script>
    function ajax1() {
        axios.get("/user")
            .then((res) => console.log("성공"))
            .catch((e) => console.log("실패"))
            .finally(() => console.log("항상 실행")); // 성공하든 실패하든 무조건 실행한다.
    }
</script>

 

예시)

직원입력 기능인데 등록누르면 중복등록막기위해 버튼 비활성화하고

등록이 완료되면 버튼다시 활성화시키기

<div>
    <h3>직원 입력</h3>
    <div>
        <input type="text" id="firstNameInput" placeholder="first name">
    </div>
    <div>
        <input type="text" id="lastNameInput" placeholder="last name">
    </div>
    <div>
        <input type="date" id="birthInput">
    </div>
    <div>
        <textarea id="notesTextArea" cols="30" rows="10"></textarea>
    </div>
    <p id="result2"></p>
    <div>
        <button onclick="ajaxAddEmployee()" id="btn">등록</button>
    </div>
</div>

<script>
    function ajaxAddEmployee() {
        const firstName = document.getElementById("firstNameInput").value;
        const lastName = document.getElementById("lastNameInput").value;
        const birthDate = document.getElementById("birthInput").value;
        const notes = document.getElementById("notesTextArea").value;
        
        // 등록 누르면 버튼 비활성화
        document.getElementById("btn").setAttribute("disabled", "disabled");

        axios.post("/main39/sub6", {
            lastName, firstName, birthDate, notes
        })
            .then(() => {
                // 성공했을 때 (2xx 응답)
                document.getElementById("result2").innerText = "등록 성공";
            })
            .catch((e) => {
                // 실패했을 때 (2xx 외 응답)
                const code = e.response.status;
                if (400 >= code && code < 500) {
                    document.getElementById("result2").innerText = "잘못된 입력";
                } else if (500 >= code && code < 600) {
                    document.getElementById("result2").innerText = "서버 오류";
                }
            })
            .finally(() => {
                // 항상 실행
                
                // then 또는 catch의 실행문이 끝나면
                // 등록버튼 다시 활성화
                document.getElementById("btn").removeAttribute("disabled");

            })

    }
</script>

API 문서: https://axios-http.com/docs/req_config

 

Request Config | Axios Docs

Request Config These are the available config options for making requests. Only the url is required. Requests will default to GET if method is not specified. { url: '/user', method: 'get', baseURL: 'https://some-domain.com/api', transformRequest: [function

axios-http.com