# HTTP 통신

HTTP는 브라우저와 서버 간에 데이터를 주고받는 통신 프로토콜이다.

> 프로토콜 : 컴퓨터나 단말기 간에 통신하기 위해 상호간 정의한 규칙

![https://poiemaweb.com/img/req\_res.png](https://3277566147-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M26jG1xuJ_y_q6GUJdp%2F-M26n5U2kzzz42LMgqau%2F-M26n7NZTpK8QZPp_fUf%2Freq_res.png?generation=1583900048637524\&alt=media)

브라우저에서 특정 데이터를 보내달라고 요청(Request)을 보내면 서버에서 응답(Response)으로 해당 데이터를 보내주는 방식으로 동작한다.

웹 앱 HTTP 통신의 대표적인 예로는 jQuery의 [ajax](https://dh00023.gitbooks.io/javascript/content/posts/2019-01-25-ajax.html) 가 있다. ajax는 서버에서 받아온 데이터를 표시할 때 화면 전체를 갱신하지 않고도 화면의 일부분만 변경할 수 있게 하는 자바스크립트 기법이다.

뷰에서도 마찬가지로 ajax를 지원하기 위한 라이브러리를 제공한다. 뷰 프레임워크의 필수 라이브러리로 관리하던 **뷰 리소스**와 **엑시오스(axios)**&#xAC00; 있다.

## 뷰 리소스

뷰 리소스를 사용하는 방법은 CDN을 이용하는 방법과 [NPM으로 라이브러리를 설치하는 방법](https://github.com/pagekit/vue-resource)(ES6 기준)이 있다.

```markup
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Vue Nested Router</title>
</head>
<body>
    <div id="app">
        <button v-on:click="getData">프레임워크 목록 가져오기</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>
    <script>
        new Vue({
            el: '#app',
            methods: {
                getData: function(){
                    this.$http.get(`https://raw.githubusercontent.com/joshua1988/doit-vuejs/master/data/demo.json`)
                    .then(function(response){
                        console.log(response);
                        console.log(response.data);
                    });
                }
            }
        });
    </script>
</body>
</html>
```

```javascript
q {url: "https://raw.githubusercontent.com/joshua1988/doit-vuejs/master/data/demo.json", ok: true, status: 200, statusText: "OK", headers: I, …}
body: {fe1: "Angular", fe2: "React", fe3: "Vue.js", fe4: "Backbone.js", be1: "Spring", …}
bodyText: "{↵    "fe1": "Angular",↵    "fe2": "React",↵    "fe3": "Vue.js",↵    "fe4": "Backbone.js",↵    "be1": "Spring",↵    "be2": "Django",↵    "be3": "Node.js"↵}↵"
headers: I {map: {…}}
ok: true
status: 200
statusText: "OK"
url: "https://raw.githubusercontent.com/joshua1988/doit-vuejs/master/data/demo.json"
data: (...)
__proto__: Object
```

```javascript
{
fe1: "Angular",
fe2: "React",
fe3: "Vue.js",
fe4: "Backbone.js",
be1: "Spring",
be2: "Django",
be3: "Node.js"
}
```

뷰 리소스에서 제공하는 API인 `this.$http.get()`을 사용해 해당 URL에서 제공하는 데이터를 받아올 수 있다. `this.$http.get()` 은 HTTP GET 요청을 서버에 보내고 특정데이터를 받아오는 것이다.

## [Axios](https://github.com/axios/axios)

Axios는 현재 뷰 커뮤니티에서 가장 많이 사용되는 HTTP 통신 라이브러리이다. Axios는 Promise 기반의 API 형식이 다양하게 제공되어 별도의 로직을 구현할 필요 없이 주어진 API만으로 간편하게 원하는 로직을 구할 수 있다.

> Promise란?
>
> 서버에 데이터를 요청하여 받아오는 동작과 같은 비동기 로직처리에 유용한 자바스크립트 객체이다. 자바스크립트는 단일 스레드로 코드를 처리하기 때문에 특정 로직의 처리가 끝날 때까지 기다려주지 않는다. **따라서 데이터를 요청하고 받아올 때까지 기다렸다가 화면에 나타나는 로직을 수행해야하는 경우에 주로 Promise를 사용한다.**
>
> [더 자세히 알아보기](https://dh00023.gitbooks.io/javascript/content/posts/2019-01-23-promise.html)

Axios는 CDN과 NPM을 이용해 설치할 수 있다.

*   HTTP GET 요청

    ```javascript
    axios.get('url').then().catch();
    ```

    해당 URL주소에 대해 HTTP GET 요청을 보낸다. 서버에서 보낸 데이터를 정상적으로 받아오면 then()안에 정의한 로직이 실행되고, 오류가 발생하면 catch()에 정의한 로직이 수행된다.
* HTTP POST 요청

```javascript
axios.post('url').then().catch();
```

해당 URL주소에 대해 HTTP POST 요청을 보낸다. 서버에서 보낸 데이터를 정상적으로 받아오면 then()안에 정의한 로직이 실행되고, 오류가 발생하면 catch()에 정의한 로직이 수행된다.

* HTTP 요청에 대한 옵션 속성 정의

```javascript
axios({
  method: 'get',
  url: 'URL 주소',
  ...
});
```

HTTP 요청에 대한 자세한 속성들(데이터 요청을 보낼 url, 요청방식, 보내는 데이터 유형, 기타 등등)을 직접 정의해 보낼 수 있다.

```markup
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>axios</title>
</head>
<body>
    <div id="app">
        <button v-on:click="getData">프레임워크 목록 가져오기</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        new Vue({
            el: '#app',
            methods: {
                getData: function(){
                    axios.get(`https://raw.githubusercontent.com/joshua1988/doit-vuejs/master/data/demo.json`)
                    .then(function(response){
                        console.log(response);
                    });
                }
            }
        });
    </script>
</body>
</html>
```

```javascript
{data: {…}, status: 200, statusText: "OK", headers: {…}, config: {…}, …}
config: {url: "https://raw.githubusercontent.com/joshua1988/doit-vuejs/master/data/demo.json", method: "get", headers: {…}, transformRequest: Array(1), transformResponse: Array(1), …}
data: {fe1: "Angular", fe2: "React", fe3: "Vue.js", fe4: "Backbone.js", be1: "Spring", …}
headers: {cache-control: "max-age=300", content-length: "106", content-type: "text/plain; charset=utf-8", expires: "Thu, 17 Oct 2019 14:43:54 GMT"}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
status: 200
statusText: "OK"
__proto__: Object
```
