如何在FastAPI表单输入时避免页面重载
实现FastAPI表单无刷新动态展示计算结果
我有一个基于FastAPI的简单程序,可将输入的浮点数乘以2并在HTML中展示结果;该数值通过HTML表单输入。想实现结果的动态展示,按下回车或提交按钮时不触发页面重载。
现有代码如下:
double.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Hello World</title> </head> <body> <h1>Hello World!</h1> <form method="post"> <input type="number" step="0.00000001" name="num"/> <input type="submit"/> </form> <p>Result: {{ result }}</p> </body> </html>
main.py
from fastapi import FastAPI, Request, Form from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates import uvicorn app = FastAPI() templates = Jinja2Templates(directory="templates") @app.get("/", response_class=HTMLResponse) async def double_num(request: Request): result = "Type a number" return templates.TemplateResponse('double.html', context={'request': request, 'result': result}) @app.post("/", response_class=HTMLResponse) async def double_num(request: Request, num: float = Form(...)): result = num*2 return templates.TemplateResponse('double.html', context={'request': request, 'result': result}) if __name__ == "__main__": uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
我注意到已有类似问题,但相关方案多涉及jQuery/JavaScript,这里可以用原生JavaScript结合FastAPI接口调整来实现,无需依赖第三方库。
解决方案
1. 修改FastAPI后端,新增计算接口
新增一个专门处理数值计算的API接口,返回JSON格式结果,替代原来返回HTML模板的POST接口:
from fastapi import FastAPI, Request, Body from fastapi.responses import HTMLResponse, JSONResponse from fastapi.templating import Jinja2Templates import uvicorn app = FastAPI() templates = Jinja2Templates(directory="templates") @app.get("/", response_class=HTMLResponse) async def double_num(request: Request): result = "Type a number" return templates.TemplateResponse('double.html', context={'request': request, 'result': result}) # 新增的计算接口,返回JSON格式结果 @app.post("/calculate") async def calculate(num: float = Body(...)): return JSONResponse(content={"result": num * 2}) if __name__ == "__main__": uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
2. 修改前端HTML,添加原生JS实现无刷新请求
去掉表单的method属性,添加JavaScript代码监听提交事件,阻止页面刷新,通过fetch异步请求后端接口并更新结果:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Hello World</title> </head> <body> <h1>Hello World!</h1> <form id="calcForm"> <input type="number" step="0.00000001" name="num" id="numInput"/> <input type="submit" value="Calculate"/> </form> <p>Result: <span id="result">{{ result }}</span></p> <script> const form = document.getElementById('calcForm'); const resultSpan = document.getElementById('result'); const numInput = document.getElementById('numInput'); form.addEventListener('submit', async (e) => { // 阻止表单默认提交行为,避免页面刷新 e.preventDefault(); const num = parseFloat(numInput.value); if (isNaN(num)) { resultSpan.textContent = "Please enter a valid number"; return; } try { // 发送异步POST请求到后端计算接口 const response = await fetch('/calculate', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ num: num }), }); const data = await response.json(); // 更新页面结果展示 resultSpan.textContent = data.result; } catch (error) { resultSpan.textContent = "Error calculating result"; } }); </script> </body> </html>
效果说明
启动服务后,输入有效数字点击提交按钮或按下回车键,页面不会刷新,结果会实时更新到页面的Result区域;如果输入无效内容,会提示错误信息。
内容的提问来源于stack exchange,提问作者joebob
相关产品推荐
相关产品推荐

