第2周 Day 1:前端转型AI,Flask 入门,Web 版开始!🎯

0 阅读7分钟

学习目标

  • 搭建 Flask 环境,理解 Flask 是什么(搞定!✅)
  • 做一个最简单的 Web 版聊天页面(搞定!✅)
  • 理解前端和后端是怎么配合工作的(搞定!✅)

一、Flask 是什么?

Flask 欢迎您 — Flask 文档 (3.1.x) - Flask 框架

Flask 是一个轻量级的 WSGI Web 应用程序框架。它的设计宗旨是使入门快速而简单,并能够扩展到复杂的应用程序。

之前我们做的英语 Agent 是在命令行里跑的第1周 Day 4:前端转型AI,参数调优🎯

你输入文字 → Python 程序处理 → 结果打印在终端

现在我们要做一个网页版

浏览器打开网页 → 点击按钮/输入文字 → Python 后端处理 → 结果显示在网页上

Flask 就是用来在 Python 里写"网页后端"的工具。

它的作用是:

  • 接收浏览器发来的请求
  • 处理逻辑(比如调用 AI)
  • 把结果返回给浏览器

二、最简单的 Flask 程序

2.1 先跑起来

新建一个文件 app.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "你好,这是我的第一个 Flask 程序!"

if __name__ == "__main__":
    app.run(debug=True)

运行后看到:

* Running on http://127.0.0.1:5000

打开浏览器,访问 http://127.0.0.1:5000,就能看到 "你好,这是我的第一个 Flask 程序!"

2.2 代码拆解

from flask import Flask

导入 Flask,就像之前 import requests 一样。

app = Flask(__name__)

创建一个 Flask 应用实例。__name__ 是 Python 内置变量,表示当前文件名,不用管为什么,照写就行。

@app.route("/")
def hello():
    return "你好..."

这是 Flask 的核心概念:路由(route)

  • @app.route("/") 表示:当浏览器访问根路径 / 时,执行下面的函数
  • 函数返回的内容,就是浏览器看到的内容
if __name__ == "__main__":
    app.run(debug=True)

启动 Flask 服务器。debug=True 表示开发模式,代码改了会自动重启,方便调试。


三、返回 HTML 页面

刚才返回的是纯文本,现在返回一个真正的网页。

3.1 创建 templates 目录

Flask 默认把 HTML 文件放在 templates 目录里:

01_flask_hello/
├── app.py
└── templates/
    └── index.html

3.2 写一个简单的 HTML

templates/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>英语学习 Agent</title>
  </head>
  <body>
    <h1>欢迎来到英语学习 Agent</h1>
    <p>点击下方按钮开始学习</p>
    <button onclick="alert('功能还没做好')">今日单词</button>
  </body>
</html>

3.3 Flask 返回这个 HTML

修改 app.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html")  # 返回 HTML 页面

if __name__ == "__main__":
    app.run(debug=True)

render_template 就是把 HTML 文件读取并返回给浏览器。


四、让页面能聊天

现在页面只有一个按钮,点击后弹个提示。我们要做一个能真正聊天的页面。

4.1 加个输入框和聊天区域

修改 templates/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>简单聊天</title>
    <style>
      body {
        font-family: sans-serif;
        max-width: 600px;
        margin: 20px auto;
      }
      #chat-box {
        border: 1px solid #ccc;
        height: 300px;
        overflow-y: scroll;
        padding: 10px;
      }
      .message {
        margin: 5px 0;
      }
      .user {
        color: blue;
      }
      .ai {
        color: green;
      }
      #input-area {
        margin-top: 10px;
      }
      #user-input {
        width: 70%;
        padding: 5px;
      }
      #send-btn {
        padding: 5px 15px;
      }
    </style>
  </head>
  <body>
    <h1>简单聊天</h1>

    <!-- 聊天记录显示区域 -->
    <div id="chat-box"></div>

    <!-- 输入区域 -->
    <div id="input-area">
      <input type="text" id="user-input" placeholder="输入内容..." />
      <button id="send-btn">发送</button>
    </div>

    <script>
      // 点击发送按钮
      document.getElementById("send-btn").onclick = function () {
        sendMessage();
      };

      // 按回车也能发送
      document.getElementById("user-input").onkeypress = function (e) {
        if (e.key === "Enter") {
          sendMessage();
        }
      };

      function sendMessage() {
        var input = document.getElementById("user-input");
        var text = input.value.trim();

        if (text === "") return;

        // 显示用户消息
        addMessage("user", text);

        // 清空输入框
        input.value = "";

        // 发给后端(后面实现)
        // TODO: 调用后端 API
      }

      function addMessage(role, text) {
        var chatBox = document.getElementById("chat-box");
        var div = document.createElement("div");
        div.className = "message " + role;
        div.innerText = role === "user" ? "你: " + text : "AI: " + text;
        chatBox.appendChild(div);

        // 滚动到底部
        chatBox.scrollTop = chatBox.scrollHeight;
      }
    </script>
  </body>
</html>

4.2 代码解释

HTML 部分

  • <div id="chat-box"> 是聊天记录显示区域
  • <input id="user-input"> 是输入框
  • <button id="send-btn"> 是发送按钮

CSS 部分

  • 给聊天区域加边框、限制高度
  • 用户消息蓝色,AI 消息绿色
  • 超出高度时可以滚动

JavaScript 部分

  • sendMessage() 函数:获取输入内容,显示在聊天区域
  • addMessage() 函数:往聊天区域添加一条消息
  • 点击按钮或按回车都能触发发送

五、连接后端 API

现在前端只能显示用户输入,还不能真正调用 AI。我们需要:

  1. Flask 后端提供一个 API 接口
  2. 前端用 JavaScript 调用这个接口
  3. 后端调用 AI,返回结果给前端

5.1 Flask 后端加一个 API

修改 app.py

from flask import Flask, render_template, request, jsonify
import requests

app = Flask(__name__)

# AI API 配置
AI_URL = "http://xxx:port/v1-openai/chat/completions"
AI_HEADERS = {
    "Content-Type": "application/json",
    "Authorization": "Bearer your-api-key"
}

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/chat", methods=["POST"])
def chat():
    # 获取前端发来的消息
    user_message = request.json.get("message", "")

    # 调用 AI
    data = {
        "model": "your-model",
        "messages": [{"role": "user", "content": user_message}]
    }

    response = requests.post(AI_URL, headers=AI_HEADERS, json=data, timeout=60)

    if response.status_code == 200:
        ai_reply = response.json()["choices"][0]["message"]["content"]
        return jsonify({"reply": ai_reply})
    else:
        return jsonify({"reply": "抱歉,出错了"}), 500

if __name__ == "__main__":
    app.run(debug=True)

5.2 前端调用这个 API

我们这版使用post请求,下次咱们改为sse的,流式输出更加友好。

修改 templates/index.html 的 JavaScript 部分:

function sendMessage() {
  var input = document.getElementById("user-input");
  var text = input.value.trim();

  if (text === "") return;

  // 显示用户消息
  addMessage("user", text);

  // 清空输入框
  input.value = "";

  // 调用后端 API
  fetch("/chat", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ message: text }),
  })
    .then(function (response) {
      return response.json();
    })
    .then(function (data) {
      // 显示 AI 回复
      addMessage("ai", data.reply);
    })
    .catch(function (error) {
      addMessage("ai", "网络出错了");
    });
}

5.3 解释一下

Flask 后端

  • @app.route("/chat", methods=["POST"]) 定义了一个 API,路径是 /chat,只接受 POST 请求
  • request.json.get("message") 获取前端发来的 JSON 数据中的 message 字段
  • jsonify() 把 Python 字典转成 JSON 返回给前端

前端 JavaScript

  • fetch() 是浏览器内置的发送网络请求的方法
  • method: "POST" 用 POST 方法
  • body: JSON.stringify({ message: text }) 把数据转成 JSON 发过去
  • .then() 是处理返回结果的回调函数

六、知识点总结

概念是什么
FlaskPython 的 Web 框架,用来写后端
路由 (@app.route)定义"访问什么路径时执行什么函数"
render_template返回 HTML 页面给浏览器
templates 目录Flask 默认存放 HTML 的地方
API后端提供的接口,前端调用它获取数据
fetch前端 JavaScript 发送网络请求的方法
jsonify把 Python 数据转成 JSON 返回
POST 请求带数据发给后端,区别于只获取数据的 GET

动画.gif


七、踩坑记录

Q1: 用 Live Server 打开页面,/chat 返回 405 错误

咋回事:VS Code 的 Live Server(端口 5500)只是静态文件服务器,没有 Flask 后端。我访问的是 5500 端口,但 Flask API 在 5000 端口。

咋办:不要用 Live Server,直接运行 Flask:

python app.py

然后浏览器访问 http://127.0.0.1:5000(不是 5500)

Q2: ModuleNotFoundError: No module named 'flask'

咋回事:Flask 还没安装,或者装到了另一个 Python 环境

咋办:用实际运行的 Python 安装:

# 查看 Python 路径
python -c "import sys; print(sys.executable)"

# 用那个 Python 安装 Flask
D:/soft/python/python.exe -m pip install flask

Q3: /chat 返回 "AI 返回错误: 401"

咋回事:API Key 过期或失效了,认证失败

咋办

  1. 去平台重新获取有效的 API Key
  2. 更新 app.py 里的 AI_HEADERS["Authorization"]
  3. 刷新页面重试

常见平台:

Q4: 访问页面报错 TemplateNotFound

咋回事:HTML 文件没放在 templates 目录,或者目录名写错了

咋办:检查文件结构,确保 templates/index.html 存在

Q5: Flask 启动后访问不了

咋回事:可能端口被占用了,或者防火墙阻止

咋办:换个端口 app.run(port=5001),或者检查防火墙

Q6: fetch 调用 API 报错 CORS

咋回事:浏览器安全策略,阻止跨域请求

咋办:同域访问不会遇到这个问题。如果遇到,Flask 加 from flask_cors import CORS; CORS(app)

Q7: 中文乱码

咋回事:HTML 没加 <meta charset="UTF-8">

咋办:确保 HTML 头部有 charset 设置


八、今日总结

今天干了啥:

✅ 搭建了 Flask 环境
✅ 做了一个最简单的网页
✅ 理解了前端和后端是怎么配合的
✅ 做了一个能聊天的 Web 版页面

明天干嘛:把代码整理好,做一个更完整的聊天页面,加上多轮对话记忆。


记于 2026-04-09,Flask 入门,Web 版开始!

image.png