ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Ajax (Asynchronous JavaScript and XML)
    web 2020. 5. 18. 12:05

     

     

    왜 사용하는가?

    통신 과정에서 HTTP의 속성으로 인해 서버에서 응답을 한다면 연결이 끊깁니다.

    이때 데이터를 요청할때마다 데이터를 보여주는 전체 페이지를 리로드해야 한다면 매우 비효율적입니다.

    그러므로 필요한 데이터만 받아서 부분적으로 리로드하여 빠르게 원하는 데이터를 보여주는 효율적인 Ajax를 도입합니다.

     

    Ajax

    자바스크립트를 이용해서 비동기식으로 서버와 통신하는 방식입니다.

    비동기식으로써 여러 가지 일이 동시적으로 발생하기 때문에 서버와 통신하는 동안 다른 작업을 할 수 있습니다.

    덕분에 서버와 자유롭게 통신하며, 페이지를 새로고침하지 않고 부분적으로 작동되는 효율적인 웹페이지가 생성됩니다.

     


     

    Ajax 구현방법

    통신을 하기 위해서 사용하는 여러가지 API가 있습니다.

    그 중에서 XMLHttpRequest API와 fetch API를 보겠습니다.

     

    XMLHttpRequest API

    Ajax의 대표적인 API중 하나로 예전에는 일반적으로 사용하던 API이었습니다. 

    function reqListener() {
    	console.log(this.responseText);
    }
    
    let oReq = new XMLHttpRequest();
    oReq.addEventListener("load", reqListener);
    oReq.open("GET", "http://www.example.org/example.txt");
    oReq.send();

     let oReq = new XMLHttpRequest();  생성자를 이용해서 XHR 객체 인스턴스를 생성합니다.

     oReq.open("GET", "http://www.example.org/example.txt");  (HTTP요청메서드(GET),  요청 URL)

     

     

    fetch API

    복잡하고 가독성이 떨어지는 기존의 API의 단점이 보완된 API입니다. Promise를 반환값으로 가집니다.

    fetch('http:// ... /messages')
    .then(response => response.json())  // Promise 반환
    .then(data => {
    	console.log(data);
    })
    .catch(err => {
    	console.log(err);
    });

     fetch('http:// ... /messages')  fetch의 파라미터로 요청주소 또는 경로가 들어갑니다.

     .then(response => response.json())  response 객체의 body 값을 추출하기위해 타입 메서드를 사용합니다.

    json 타입 메서드를 사용했지만 Promise 값이 반환되고, 두번때 then 메서드에서 원하는 json

     


     

     

    fetch API (POST)

    fetch의 두번째 파라미터인 init객체를 통해서 POST요청을 할 수 있습니다.

    // fetch(url, init)
    fetch('http:// ... /messages', {
      method: 'POST', // or 'PUT'
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    })
    .then(response => response.json())  // Promise 반환
    .then(data => {
    	console.log(data);
    })
    .catch(err => {
    	console.log(err);
    });

     

    fetch의 옵션과 디테일

    // Example POST method implementation:
    async function postData(url = '', data = {}) {
      // Default options are marked with *
      const response = await 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
        referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
        body: JSON.stringify(data) // body data type must match "Content-Type" header
      });
      return response.json(); // parses JSON response into native JavaScript objects
    }
    
    postData('https://example.com/answer', { answer: 42 })
      .then(data => {
        console.log(data); // JSON data parsed by `response.json()` call
      });

     

     

    fetch를 통해서 다른 서버에 POST요청을 하게 된다면 CORS(Cross Origin Resource Sharing)를 사용하게 됩니다.

    CORS는 웹의 서버가 아닌 다른 서버로 리소스를 요청할 경우에 접근할 수 있는 권한을 부여받는 체제입니다.

    CORS

    cross origin 에서 리소스를 요청하여 사용하는 과정에서

    보안 상의 이유로 서버가 허용한 범위안에서 cross origin 요청이 허용됩니다.

    const defaultCorsHeaders = {
        //허용되는 도메인(*)
        'access-control-allow-origin': '*',
        //허용되는 메서드
        'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS',
        //허용되는 헤더내용
        'access-control-allow-headers': 'content-type, accept',
        //preflight request 허용시간
        'access-control-max-age': 10
    }

     

     

    단순 요청과 프리플라이트 요청

    서버 데이터에 부수 효과(side effect)를 일으킬 수 있는 HTTP요청 메서드에 대해, CORS 명세는 브라우저가 요청을 OPTIONS메서드로 "프리플라이트"(preflight, 사전 전달)하여 서버의 허가를 받은 후에 실제 요청을 보내도록 요구합니다.

     

     

     

     

     

    'web' 카테고리의 다른 글

    (준비중) socket.io  (0) 2020.09.04
    배포하기  (0) 2020.06.22
    데이터베이스 (Database)  (0) 2020.06.21
    React  (0) 2020.06.07
    인터넷 (The Internet)  (0) 2020.05.24

    댓글

Designed by CHANUL