はじめに
初歩的な内容かもしれませんが、備忘録として残しておきます。
解釈の違いや指摘すべき点があれば是非お教えください。
また、Vueプロジェクト(Vue3)はnpm init vue@latest
にて作成したものです。
フロントエンド(Vue.js)はnpm run dev
、
バックエンド(FastAPI)はuvicorn main:app --reload
で起動しました。
ここでのapp
はmain.py
のFastAPI()
インスタンスを格納した変数に連動しています。適宜置き換えてください。
実行環境
- macOS Monterey バージョン12.6.3
- node: 16.19.1
- npm: 8.19.3
- axios: 1.3.4
- fastapi: 0.92.0
- uvicorn: 0.20.0
発生した問題
Vueプロジェクトを作成し、テスト用のmain.py
と__init__.py
を用意して、それぞれのディレクトリでlocalhostを立てて動作確認しようとしたら、404 (Not Found)
もといAxiosError
が投げられました。
原因
VueプロジェクトとFastAPIでのアドレスが異なっていたため、作ったAPIにアクセスできなかったようです。
http://localhost:5173 #フロントエンドへのアクセス
http://localhost:8000 #バックエンドへのアクセス
解決策
vite.config.ts
に、開発サーバのカスタムプロキシのルールを設定することで解決しました。テストに用いた各種ソースコードを以下に記載しています。
vite.config.ts
は、Vueプロジェクト作成時にTypeScriptを選択した場合のファイルであり、TypeScriptを選択していない場合はvite.config.js
になっていると思います。
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
app = FastAPI()
# CORS対策
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
@app.get("/api/test")
def test():
return "test"
<script setup lang="ts">
import axios from "axios";
import { ref } from "vue";
const test = ref("");
async function getTest() {
await axios
.get("/api/test")
.then((res) => (test.value = res.data))
.catch((e) => {
console.log(e);
});
}
</script>
<template>
<button @click="getTest">getTest</button>
<p>{{ test }}</p>
</template>
以下のように変更しました。proxy
の内容はFastAPIにアクセスする際のアドレスにしています。
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
+ server: {
+ proxy: {
+ "/api": "http://localhost:8000",
+ },
+ },
});
コードの加筆後、npm run dev
およびuvicorn main:app --reload
を実行し、サーバーを立ち上げた結果、ブラウザ上のボタンを押すとtest
という文字列が返ってくるようになりました!