关于FastAPI与Vue3的通信

发布时间 2023-11-22 22:33:51作者: pu369com

学习一下前后端分离技术,前端采用三大框架之一的Vue.js,后端则采用PythonFastAPI框架。

一、前端设计

1.建目录 mydemo

2.在mydemo目录下打开命令行,运行:npm init vue@latest

(这里如果cmd卡死了,就ctrl + C 结束,再次运行npm init vue@latest )

3.工程名设置为 frontend  ,其余按默认

4.按提示依次运行:

 cd frontend
 npm install
 npm run dev

5.此时在浏览器中输入网址:http://127.0.0.1:5173/ (或者:http://localhost:5173),即会看到页面

对于前端,我们主要编辑 mydemo\frontend\src 下的文件:

6.修改 App.vue 内容如下:

<script>
export default {
  data() {
    return {
      msg: "你好,世界!",
    };
  },  
};
</script>

<template>  
    <button >第一个按钮</button>
    <p>{{ msg }}</p>  
</template>

只需要保存,页面立即改变(热更新)。

至此,我们完成了前端的示例。

二、后端设计

1.安装FastAPI ,在命令窗口运行:

pip install fastapi
pip install "uvicorn[standard]"

接下来在mydemo文件夹下创建一个backend文件夹,用以存放后端文件:

cd mydemo
mkdir backend

2.在backend文件夹中创建一个main.py文件,其中代码如下:

from fastapi import FastAPI
app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

保存后,在backend路径的命令窗口运行以下代码:

uvicorn main:app --reload  --port 8001

在浏览器地址栏输入http://127.0.0.1:8001即可看到后端服务器返回的页面

至此,后端服务器的最小例子也建立了。

三、前端获取后端的数据

这时需要用到两个包,即前端需要用到axios这个包,后端则要用到CORS这个中间件。

1.前端, 安装axios,在frontend文件夹的命令窗口下运行以下命令: 

npm install axios

修改frontend/src/main.js文件如下:

import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'

import axios from 'axios'
axios.defaults.withCredentials = true;
axios.defaults.baseURL = 'http://127.0.0.1:8001'

createApp(App).mount('#app')

上面代码的目的是:导入axios,并且告诉前端axios,后端地址是http://127.0.0.1:8001

2. 接着在frontend/src/App.vue中,添加获取数据的代码如下: 

<script>
  import axios from "axios";
  export default {
    data() {
      return {
        msg: "你好,世界!",
      };
    },
    methods: {  
      getMessage() {
        axios.get("/").then((res) => {
          this.msg = res.data;        
        });
      },    
  },
};
</script>

<template>  
    <button @click="getMessage">第一个按钮</button>
    <p>{{ msg }}</p>  
</template>

在上述代码中,给按钮绑定了一个click事件,当这个按钮被点击时,它会调用getMessage()函数,该函数中用axios去获得后端根目录下的数据,然后将要显示的文字更改为相应的返回值{hello:world}

至此,前端配置完成,当然,此时点击页面按钮不会有任何反应,如果打开网页开发工具中的控制台,你会看到有关  跨域资源共享 (CORS) 的错误信息:

3. 后端的设置

FastAPI中,设置CORS是很简单的,只不过要注意的是,当前端的axios.defaults.withCredentials设置为true时,后面的响应地址就必须明确为字符串,而不能是一个列表,这里的意思是,当跨域访问需要带session时,只能响应确定的地址请求。

添加中间件CORS的代码至后端的main.py, 如下:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()
app.add_middleware(
    CORSMiddleware,    
    allow_origins= "http://127.0.0.1:5173/",    
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],    
)

@app.get("/")
def read_root():
    return {"Hello": "World"}

至此,后端代码修改完毕。

此时,当点击一下页面的按钮,其下方的文字将变成后端FastAPI发送的信息 (我这里还是不行,可能是在局域网中的原因,需要将上面代码中的http://127.0.0.1:5173 改为 http://localhost:5173/ 才行)

这就完成了从服务器端获取数据的过程。

四、前端向后端发送数据

1.客户端设置

先在frontend/src/App.vue中添加一个发送的方法,同时添加一个按钮,当用户点击该按钮时,调用axios发送数据给服务器端,修改代码如下:

<script>
  import axios from "axios";
  export default {
    data() {
      return {
        msg: "你好,世界!",
      };
    },
    
    methods: {  
      sendMessage () { 
        axios.post(
          "/update_item/",
          {name: "张无忌", age:24},
        ).then((res) => {
          console.log(res.data);
      });
    },
      getMessage() {
        axios.get("/").then((res) => {
        this.msg = res.data;        
      });
    },    
  },
};
</script>

<template>  
    <button @click="getMessage">第一个按钮</button>
    <button @click="sendMessage">发送信息给服务器</button>
    <p>{{ msg }}</p>  
</template>

这里要注意的是,axios发送数据时,其数据是以字典的形式发送,当然也可以看作是json格式。

在这里,axios提交的路径是/update_item/,因此服务器端必须建立该路由。

2.服务器端设置

为了接受客户端提交过来的数据,要进行两步操作:一是设立相应的路由地址,二是设置接受数据的模型,此时用到pydantic,该包会在安装fastAPI时同步安装,该包的主要功能是对接口数据进行定义、检查与管理。

在下面示例中,我们定义一个Item类来接受客户端提交的数据,backend/main.py的代码修改如下:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Union

class Item(BaseModel):
    name: str
    age: float
    is_TrueMan: Union[bool, None]=None

app = FastAPI()
app.add_middleware(
    CORSMiddleware,    
    allow_origins= "http://localhost:5173/",    
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],    
)

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.post("/update_item/")
def update_item(item: Item):
    item.age += 10
    print(item)
    return {'item':item}

这里将接受到的人员年龄增加10后,打印在服务器端的控制台上,并将修改的结果返回给客户端,由客户端打印在浏览器的控制台上

至此,我们完成了一个客户端与服务器端完整的通信程序。

下一篇,我们再将vue3前端打包集成到后端fastAPI的uvicorn服务器

 

 

参考:https://zhuanlan.zhihu.com/p/632387477

https://www.jianshu.com/p/987383cf6929

https://blog.csdn.net/bosivip/article/details/128141950