티스토리 뷰

자바스크립트를 이용해서 웹브라우저의 통신 기능을 사용하는 방법을 알아본다.

Ajax(Asynchronous JavaScript and XML)

*Asynchronous adj.비동기의

: 서버와 클라이언트 간의 데이터를 주고 받는 형식으로서 JSON과 페이지 리로드 없이 웹페이지의 내용을 변경할 수 있다. 

  • 웹브라우저와 웹서버가 내부적으로 데이터 통신을 하게 한다. 
  • JS를 이용해서 비동기적으로 서버와 브라우저가 데이터를 주고 받는 방식을 말한다. 
  • 이때 사용하는 API가 XMLHttpRequest 객체이다. ->꼭 XML을 사용해서 통신해야 하는 것은 아니며 XML보단 JSON을 더 많이 사용한다.

XMLHttpRequest 

  • XMLHttpRequest (XHR) objects are used to interact with servers.
  • XMLHttpRequest is used heavily in AJAX programming.

※아래의 예제를 실행하기 위해서는 서버 환경이 구축되어 있어야 한다.

 

 


▶GET방식으로 데이터를 전송하는 방법

 

time.php //현재 시간을 출력하는 예시, 서버쪽

꼭 php가 아니어도 됩니다. node.js일수도 있고 ..

<?php
$d1 = new DateTime;
$d1->setTimezone(new DateTimezone("asia/seoul"));
echo $d1->format('H:i:s');
?>

demo1.html //time.php에 접속해서 현재 시간을 페이지에 표시한다. 

<body>
    <p>time : <span id="time"></span></p>
    <input type="button" id="execute" value="execute" />
    <script>
      document
        .querySelector("input")
        //버튼을 클릭하면 이벤트발생
        .addEventListener("click", function (event) {
        //XMLHttpRequest를 생성하고 그것을 xhr변수에 담기 
        //xhr 변수를 이용해서 객체를 제어할 수 있게 만듦
          const xhr = new XMLHttpRequest();
          //.open() -> .send()는 지켜야할 순서이다.
          //.open()의 첫번째 인자로 GET을 주고 두번째 인자로 ./time.php라는 스트링을 줌 
          //첫번째인자: 서버통신 방법을 뜻하며 GET방식으로 한다라는 의미
          //두번째인자: 서버 통신을 할 때의 리소스는 ./time.php라는 것 
          //<form method="GET" action="./time.php"
          //send()가 호출될 때 서버와 통신을 시작한다. 
          xhr.open("GET", "./time.php");
          xhr.onreadystatechange = function () {
              //.readyState ===4 현재 통신이 어떤 상태인지 알려줌 4번은 모든 통신이 끝남, 
              //.status === 200 커뮤니케이션의 결과를 의미하며 200번은 성공을 뜻함(404 not found)
              //결론적으로 통신이 완료됐고 통신에 성공했다면 내부 코드 실행
            if (xhr.readyState === 4 && xhr.status === 200) {
                //time의 콘텐츠로 서버에서 가져온 정보를 넣어준다. 
                //.responseText 서버에서 리턴해준 정보를 담고있는 프로퍼티
              document.querySelector("#time").innerHTML = xhr.responseText;
            }
          };
          xhr.send();
        });
    </script>
  </body>

xhr.open("GET", "./time.php);form태그를 개선한 것이라고 생각하면 됩니다.

->form을 쓰면 페이지가 리로드되기 때문에 그것에 대한 개선점으로 Ajax를 사용한다.

  • form 태그는 속성으로 method: 폼 전송 방식(GET/POST) / action: 폼 데이터가 전송되는 백엔드 url 를 가지며 위의 .open()예시코드와 동일하게 대치된다.
  • 접속하려는 대상을 지정한다. 첫번째 인자는 form 태그의 method에 대응하는 것으로 GET/POST 방식을 주로 사용한다. 두번째 인자는 접속하고자 하는 서버쪽 리소스의 주소로 form 태그의 action에 해당한다.

onreadystatechange 이벤트

서버와의 통신이 끝났을 때 호출되는 이벤트이다

 

.readyState: 통신의 현재 상태를 의미 

.status: HTTP 통신의 결과를 의미

.responseText : 서버에서 전송한 데이터를 담고있는 프로퍼티

 

결과: 위의 예시코드는 현재 서버에서 가져온 현재시간을 페이지 리로딩 없이 가져올 수 있다.

 


post 방식으로 데이터를 전송하는 방법

아래 예제는 시간대와 시간의 출력 형식을 지정하는 예제

 

demo2.html

<p>time : <span id="time"></span></p>
<select id="timezone">
    <option value="Asia/Seoul">asia/seoul</option>
    <option value="America/New_York">America/New_York</option>
</select>
<select id="format">
    <option value="Y-m-d H:i:s">Y-m-d H:i:s</option>
    <option value="Y-m-d">Y-m-d</option>
</select>
<input type="button" id="execute" value="execute" />
<script>
document.querySelector('input').addEventListener('click', function(event){
    const xhr = new XMLHttpRequest();
    xhr.open('POST', './time2.php');
    xhr.onreadystatechange = function(){
        document.querySelector('#time').innerHTML = xhr.responseText;
    }
    //POST방식으로 바뀌면서 새롭게 추가된 코드 
    
    //서버로 전송할 데이터 타입의 형식(MIME)을 지정
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    //전송할 데이터를 형식에 맞게 만든다. 
    const data = '';
    data += 'timezone='+document.getElementById('timezone').value;
    //구분을 위해서 &과 =을 붙여줌 
    data += '&format='+document.getElementById('format').value;
    xhr.send(data); 
});
</script>
  • 서버로 전송할 데이터를 형식에 맞게 만들어야 합니다. 
  • 이름=값&이름=값...의 형식을 지켜야 함 // 이름과 값은 = 로 구분하고 값끼리의 구분은 &으로 합니다.
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

->서버로 전송할 데이터 타입의 형식(MIME)을 지정한다. // 이 부분에 대해서는 저도 잘 모르겠네요

 

time2.php 

Ajax를 이용해서 전송한 데이터를 받아서 현재 시간을 출력해주는 서버쪽 구현

<?php
$d1 = new DateTime;
$d1->setTimezone(new DateTimezone($_POST['timezone']));
echo $d1->format($_POST['format']);
?>
댓글