axios & Django REST framework でJSONをGET/POST



前回の記事↓
[Django REST framework でJSONをGET/POST/PUT/DELETE](https://qiita.com/HIJIKI/items/a88d1ca86788bed3af9e)

サーバーサイドは[前回の記事](https://qiita.com/HIJIKI/items/a88d1ca86788bed3af9e)で作ったものを利用します

##  axiosの導入
クライアントサイドからのhttp通信にはaxiosを使います

```
$ npm install axios --save-dev
```

クライアントサイド内のaxiosを使うファイルには以下を追記しておきます

```javascript
import axios from 'axios'
```


##  GET
クライアントサイドのGETしたい場所に以下を記述します

```javascript
axios.get("http://localhost:8000/api/books/")
    .then(response=>{
      console.log("status:",response.status)
      console.log("axiosGetData:",response.data)
    })
    .catch(err=>{
      console.log("axiosGetErr",err)
    })
```

サーバーサイドを起動した状態で、クライアントサイドを実行してみてください

chromeの開発者モードでコンソールを開いてクライアントサイドのログを確認してみると
`Access to XMLHttpRequest at 'http://localhost:8000/api/books/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.`

こんなエラーメッセージが出力されているかと思います

CORSというのはCross-Origin Resource Sharingの略で、異なるオリジンへの通信を行うことです
[脱・とりあえず動く[CORS編] - Qiita](https://qiita.com/karintou/items/52ee1f7c5fa641980188)
> オリジンとは「プロトコル」+「ホスト」+「ポート番号」の組み合わせのことです

異なるオリジンへの通信をすべて許可してしまうと、セキュリティ的に問題が出てきます
そのため、特定のurlからの通信のみ許可する必要があります

[django-cors-headersの設定で軽くハマった話。 - 自称フルスタックエンジニアのぶろぐ。](https://murabo.hatenablog.com/entry/2018/02/01/121925)

サーバーサイドにdjango-cors-headersをインストールします

```
$ pip install django-cors-headers
```

settings.py内の `INSTALLED_APP`という項目にcorsheadersを追記します

```settings.py
.....

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
    'rest_framework'
+   'corsheaders'                    #追加行
]
.....
```
`MIDDLEWARE`にも２つ追加します

```settings.py
.....

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+   'corsheaders.middleware.CorsMiddleware',                   #追加行
+   'django.middleware.common.CommonMiddleware',               #追加行
]
.....
```
また新しく`CORS_ORIGIN_WHITELIST`という項目を`settings.py`内に作成します

```settings.py
.....

CORS_ORIGIN_WHITELIST = (
    'localhost:3000/',
    'localhost:3000',
)
.....
```
apiにアクセスする許可をクライアントサイドに与えました
ポート番号の部分はそれぞれの環境に合わせてください

これでもう一度GETしてみてください

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185108/bb5e8c38-0385-8bdd-03ec-a74229ca3069.png)


jsonを取得できました


##  POST
クライアントサイドのPOSTしたい場所に以下を記述します

```javascript
axios.post("http://localhost:8000/api/books/",{"title":"urasima tarou","contents":"ryu-gu no tsukai"})
    .then(response=>{console.log("body:",response.data)})
```

サーバーサイドを起動した状態で、クライアントサイドを実行してみてください

プラウザのコンソールにPOSTしたデータが表示されます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185108/da11e941-b4b2-d805-4b6d-d4c54fc4ca9a.png)


確認のためにもう一度GETしてみましょう

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185108/dc005027-63c7-2ff7-cc9d-86e9927a489d.png)


データベースに id:4 が追加されていることを確認できました