はじめに
前回は
- ✅djangoからvue cliへの移行(vue-leafletの実装など)
- ✅Vue CLIの設定
を実装できた。
今回は、
- 🔲vueとdjangoとのデータのやり取り実装
をしていく。
また、前回から時間が空いてしまった。
理由は「ゼルダの伝説」をやり込んでいた、、、
もう最高!!!!!!
やめられない!!!!!
この構図!!!!
という訳ではなく、実際はエラーと格闘して悶絶していたから。
今回の実装はvueとdjangoのやり取りの部分。
vueで入力した値をdjango側に送り、その値をdjangoで処理してvue側に返すというもの。
図にすると以下のような感じ
エラーの部分も含めて設定した部分を記録しておく。
実装
今回の実装は前回までの記事でも書いた通り、docker composeを使用しての構築だ。
今回の大本の原因を記載しておく。
そもそも、App.vueは修正して、保存すると更新がかかるが、conf.jsの方は更新がかからない?ようなので、一度、docker compose downをすることが必要になってくる。
このため修正してもエラーが消えないようなことが起こって、問題の切り分けが上手くいっていなく、それが何故か分からず時間を使ってしまっていた。
CORSの設定
CORSの設定をしていないと以下のようなエラーが出るはず。
127.0.0.1/:1 Access to XMLHttpRequest at 'http://localhost:8000/xxx/suggest-station/' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORSとは、
- オリジン間リソース共有(Cross-Origin Resource Sharing)の略
- 別のオリジン(Cross-Origin)からのリクエストを共有するかどうか決定できる仕組み
です。
まずはインストール。
$ pip3 install django-cors-headers
settings.pyに以下を追記。
INSTALLED_APPS = [
・・・【略】・・・
'corsheaders',
]
MIDDLEWARE = [
・・・【略】・・・
'corsheaders.middleware.CorsMiddleware',
]
CORS_ALLOWED_ORIGINS = [
"http://frontend:8080",
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'access-control-allow-origin',
)
エラー悶絶記録
corsの設定をして、corsのエラーが消えたが、ここでエラーが発生。(ここからエラー地獄に悩まされる)
名前解決ができていないよう。
"AxiosError: Network Error\n at XMLHttpRequest.handleError (webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:160:14)"
backendはできると思ったんだけどな。。。
ちなみにdocker-compose.yamlは以下のようになっている。
version: '3.8'
services:
nginx:
image: nginx:latest
container_name: nginx-container
restart: always
ports:
- "80:80"
- "443:443"
・・・【略】・・・
frontend:
container_name: frontend-container
build:
context: ./vue
dockerfile: ./Dockerfile
ports:
- 8080:8080
・・・【略】・・・
backend:
container_name: backend-container
build:
context: ./django
dockerfile: ./Dockerfile
・・・【略】・・・
db:
container_name: db-container
build:
context: ./db
dockerfile: ./Dockerfile
・・・【略】・・・
一応以下のサイトを参考にIPを指定して対応。
Docker環境でAPI通信にハマった話:Failed to load resource: net::ERR_NAME_NOT_RESOLVED – 解決方法まとめ #Rails – Qiita
するとエラーが変わる。
Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
vue側からdjango側へのコネクションがタイムアウトになるとのことなので、一旦、vueを積んだdocker containerからdjangoへの疎通を確認する。
すると、以下のように繋がっているっぽい。
# wget -O - http://172.19.0.4:8000/xxx/datetime/
Connecting to 172.19.0.4:8000 (172.19.0.4:8000)
writing to stdout
- 100% |*************************************************| 17 0:00:00 ETA
written to stdout
ちなみに、ここからは以前ローカルで実装したdatetimeのAPIを使用することにする。(こちらの記事で記載)
つまりローカルでは接続が確認できていれば、docker側の問題か、そのコード自体の問題か切り分けができると思ったからだ。
そして、この時、docker compose downやdocker compose upを繰り返していたか、
backendにしても名前解決のエラーが起こらないようになっている。。。
マジ謎。。。
AxiosError: Request failed with status code 404
実際にアクセスしてみると、
8000/datetime/ で404エラーになっていることが分かった。
vue.config.jsに以下の設定があったからリライトされていた。
proxy: {
"/app": {
//target: "http://172.18.0.4:8000",
target: "http://backend:8000",
changeOrigin: true,
pathRewrite: {
'^/app': '',
},
},
対象部分を削除して、
docker compose downとdocker compose upをしたら直った。
緑のマーカ部分。しっかり時間がdjango側から取得できて表示されていることが分かる。
これでvueとdjangoとのデータのやりとりはできることが確認できた。
ここまでくれば、以下のように駅の情報を取ってくるような処理もdjango側でとってきた値をvueに渡すことでできる。
django自動更新のススメ
vue側でvue.config.jsを修正して、保存するだけでは更新されないが、djangoのviews.pyの設定なども同様である。
毎回、docker compose downとdocker compose upをするのは手間なので以下の設定をdango起動時のスクリプトに組み込んだ。
# ファイルの変更を検知し、サーバーを再起動するコマンド例
watchmedo auto-restart --directory=/code --pattern=*.py --recursive -- django-admin runserver 0.0.0.0:8000
宿泊場所の値もとってこれるようになった。
まとめ
今回は
- ✅vueとdjangoとのデータのやり取り実装
を対応した。
これで対応したものは以下のようになった。(✅の項目が対応済みのもの)
- ✅DjangoとVue.jsとの接続確認
- ✅Nginxのコンテナ化(フロントエンド)
- ✅Vue.jsのコンテナ化とVue.jsとNginxの接続(フロントエンド)
- ✅Djangoのコンテナ化(バックエンド)
- ✅mysqlのコンテナ化(バックエンド)
- ✅djangoからvue cliへの移行(vue-leafletの実装など)
- ✅Vue CLIの設定
- ✅vueとdjangoとのデータのやり取り実装
- 🔲プロダクトデザインから収益化をちゃんと考えたプロダクトを考える(前回と変更した項目)
- 🔲証明書の自動更新
次回は
- 🔲プロダクトデザインから収益化をちゃんと考えたプロダクトを考える
を実施していく。
僕も使っている、SakuraのVPSサーバー。この記事のサービスもこのVPSサーバーで動いています。👇
ドメインはこちらでも取得可能!👇