实现 FastAPI 跨域配置与 Vue 响应式交互的手写数字识别

后端 FastAPI 配置

FastAPI 后端需要配置 CORS 中间件以允许跨域请求。安装依赖库 fastapiuvicorn,同时安装机器学习相关库如 numpytensorflow(用于手写数字识别模型)。

from fastapi import FastAPI, UploadFile, File
from fastapi.middleware.cors import CORSMiddleware
import numpy as np
import tensorflow as tf
from PIL import Image
import io

app = FastAPI()

# 配置 CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 允许所有源,生产环境应限制为具体域名
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 加载预训练模型(示例为 MNIST 模型)
model = tf.keras.models.load_model("mnist_model.h5")

@app.post("/predict")
async def predict(file: UploadFile = File(...)):
    contents = await file.read()
    image = Image.open(io.BytesIO(contents)).convert("L")
    image = image.resize((28, 28))
    image_array = np.array(image).reshape(1, 28, 28, 1) / 255.0
    prediction = model.predict(image_array)
    return {"prediction": int(np.argmax(prediction))}

前端 Vue 实现

Vue 前端通过 axios 发送图片数据到 FastAPI 后端,并处理响应式结果。确保安装 axiosvue 依赖。

<template>
  <div>
    <input type="file" @change="handleFileUpload" accept="image/*" />
    <button @click="submitImage">识别数字</button>
    <p>预测结果: {{ prediction }}</p>
  </div>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      imageFile: null,
      prediction: null,
    };
  },
  methods: {
    handleFileUpload(event) {
      this.imageFile = event.target.files[0];
    },
    async submitImage() {
      if (!this.imageFile) return;
      const formData = new FormData();
      formData.append("file", this.imageFile);
      try {
        const response = await axios.post("http://localhost:8000/predict", formData, {
          headers: { "Content-Type": "multipart/form-data" },
        });
        this.prediction = response.data.prediction;
      } catch (error) {
        console.error("Error:", error);
      }
    },
  },
};
</script>

模型训练与部署

使用 TensorFlow 训练一个简单的 MNIST 手写数字识别模型,保存为 mnist_model.h5 供 FastAPI 加载。

import tensorflow as tf
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation="relu"),
  tf.keras.layers.Dense(10, activation="softmax")
])
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(x_train, y_train, epochs=5)
model.save("mnist_model.h5")

运行与测试

启动 FastAPI 后端服务:

uvicorn main:app --reload

启动 Vue 前端项目后,上传手写数字图片即可看到预测结果。确保后端地址与前端请求的 axios.post URL 一致。

更多推荐