You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI页面切换异常:点击返回按钮无法渲染初始表单页

问题分析

你遇到的核心问题是:当通过innerHTML替换整个页面HTML内容时,浏览器不会自动执行新HTML中的<script>标签代码。从结果页返回表单页后,form.html里的submit()函数没有被定义,导致表单看似渲染但无法正常工作(或你感知到“无法渲染”)。

另外注意到你代码里的模板目录拼写为templetes(正确拼写应为templates),如果实际目录名和代码不一致会导致模板加载失败,建议统一修正。

解决方法

方法一:保持无刷新体验,手动执行脚本

这种方法保留当前的无刷新替换逻辑,但在替换HTML后手动提取并执行新页面的脚本:

修改result.html的脚本

<script>
function displayHTML() {
    fetch("/", { method: "GET" })
        .then(response => response.text())
        .then(html => {
            const htmlElement = document.getElementsByTagName("html")[0];
            htmlElement.innerHTML = html;
            
            // 提取并执行新页面中的所有脚本
            const scripts = htmlElement.getElementsByTagName("script");
            Array.from(scripts).forEach(script => {
                const newScript = document.createElement("script");
                if (script.src) {
                    newScript.src = script.src;
                } else {
                    newScript.textContent = script.textContent;
                }
                document.head.appendChild(newScript);
                // 执行后移除临时脚本,避免重复加载
                newScript.remove();
            });
        });
}
window.displayHTML = displayHTML;
</script>

修改form.html的脚本(确保submit函数全局可访问)

<script>
// 将submit函数绑定到window,避免作用域问题
window.submit = function() {
    const name = document.getElementById("first").value;
    const date = document.getElementById("dob").value;
    
    fetch("/result", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: name, date: date })
    })
    .then(response => response.text())
    .then(html => {
        const htmlElement = document.getElementsByTagName("html")[0];
        htmlElement.innerHTML = html;
        
        // 同样执行结果页的脚本
        const scripts = htmlElement.getElementsByTagName("script");
        Array.from(scripts).forEach(script => {
            const newScript = document.createElement("script");
            if (script.src) {
                newScript.src = script.src;
            } else {
                newScript.textContent = script.textContent;
            }
            document.head.appendChild(newScript);
            newScript.remove();
        });
    })
}
</script>

方法二:改用页面跳转(更简单可靠)

如果不需要严格的无刷新体验,直接用window.location.href跳转,浏览器会完整加载页面并自动执行所有脚本,实现起来更简单:

调整后端代码(支持GET请求返回结果页)

from fastapi import FastAPI, Request, Query
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel

app = FastAPI()
# 修正模板目录拼写(如果实际目录是templates的话)
templates = Jinja2Templates(directory="templates")

class InputData(BaseModel):
    name : str
    date : str

# 新增GET接口支持参数传递
@app.get("/result")
async def get_result_get(request: Request, name: str = Query(...), date: str = Query(...)):
    data = {
        "name": name,
        "dob": date
    }
    return templates.TemplateResponse("result.html", {"request": request, "data": data})

# 保留原POST接口
@app.post("/result")
async def get_result_post(request: Request, input: InputData):
    data = {
        "name": input.name,
        "dob": input.date
    }
    print(data)
    return templates.TemplateResponse("result.html", {"request": request, "data": data})

@app.get("/")
async def root(request : Request):
    return templates.TemplateResponse("form.html" , {"request" : request})

修改form.html的submit函数

<script>
function submit() {
    const name = document.getElementById("first").value;
    const date = document.getElementById("dob").value;
    // 跳转到结果页并传递参数
    window.location.href = `/result?name=${encodeURIComponent(name)}&date=${encodeURIComponent(date)}`;
}
</script>

修改result.html的返回按钮

<button onclick="window.location.href = '/'">Back</button>
总结
  • 方法一适合需要无刷新体验的场景,但需要处理脚本执行逻辑;
  • 方法二更简单可靠,兼容性更好,适合大多数普通Web场景。

内容的提问来源于stack exchange,提问作者Gaurav Monga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:07:11