【问题标题】:How to send a FastAPI response without redirecting the user to another page?如何在不将用户重定向到另一个页面的情况下发送 FastAPI 响应?
【发布时间】:2022-08-15 14:12:14
【问题描述】:

我正在使用 FastAPI 创建一个 API,它从 HTML 页面接收form-data,处理数据(需要一些时间)并返回一条消息,说明此任务已完成。

这是我的后端:

from cgi import test
from fastapi import FastAPI, Form, Request
from starlette.responses import FileResponse

app = FastAPI()

@app.post(\"/\")
async def swinir_dict_creation(request: Request,taskname: str = Form(...),tasknumber: int = Form(...)):

    args_to_test = {\"taskname\":taskname, \"tasknumber\":tasknumber} # dict creation
    print(\'\\n\',args_to_test,\'\\n\')
    # my_function_does_some_data_treatment.main(args_to_test)
    # return \'Treating...\'
    return \'Super resolution completed! task \'+str(args_to_test[\"tasknumber\"])+\' of \'+args_to_test[\"taskname\"]+\' done\'

@app.get(\"/\")
async def read_index():
    return FileResponse(\"index.html\")

这是我的前端代码:

<html>
   <head>
      <h1><b>Super resolution image treatment</b></h1>   
      <body>
        <form action=\"http://127.0.0.1:8000/\" method=\"post\" enctype=\"multipart/form-data\">

            <label for=\"taskname\" style=\"font-size: 20px\">Task name*:</label>
            <input type=\"text\" name=\"taskname\" id=\"taskname\" />
    
            <label for=\"tasknumber\" style=\"font-size: 20px\">Task number*:</label>
            <input type=\"number\" name=\"tasknumber\" id=\"tasknumber\" />

            <b><p style=\"display:inline\"> * Cannot be null</p></b>
            <button type=\"submit\" value=\"Submit\">Start</button>
         </form>
      </body>
   </head>
</html>

所以前端页面是这样的:

当后端处理完成后,用户提交了一些数据后,FastAPI 后端的 return 语句只是将用户重定向到一个只显示返回消息的新页面。我正在寻找一种替代方案,它可以保持 HTML 表单出现并在此表单下方显示从服务器返回的消息。例如:

我在FastAPI documentation about requests 中进行了搜索,但没有找到任何可以避免修改我的原始 HTML 页面的内容。

  • 您需要使用 Fetch API 之类的东西对 API 进行 AJAX 调用。与How can I make an AJAX call without jQuery? 重复
  • @esqew,可能是这样,但我在这里得到的答案更清楚地解决了问题,而且它还展示了如何将它与 HTML 代码集成。因此,我会检查“不重复”,以考虑未来可能有同样疑问的人。

标签: python html forms fastapi


【解决方案1】:

您需要使用 Javascript 接口/库(例如 Fetch API)来发出异步 HTTP 请求。此外,您应该使用Templates 来呈现并返回TemplateResponse,而不是FileResponse,如您的代码所示。下面给出示例。如果您想发布JSON 数据,请查看this answer,同时发布FilesForm/JSON 数据,请查看this answer

应用程序.py

from fastapi import FastAPI, Form, Request
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory="templates")

@app.post("/submit")
async def submit(request: Request, taskname: str = Form(...), tasknumber: int = Form(...)):
    return f'Super resolution completed! task {tasknumber} of {taskname} done'

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

模板/索引.html

<html>
   <head>
      <script type="text/javascript">
         function submitForm() {
             var formElement = document.getElementById('myForm');
             var data = new FormData(formElement);
             fetch('/submit', {
                   method: 'POST',
                   body: data,
                 })
                 .then(response => response.text())
                 .then(data => {
                   document.getElementById("responseArea").innerHTML = data;
                 })
                 .catch(error => {
                   console.error(error);
                 });
         }
      </script>
   </head>
   <body>
      <h1>Super resolution image treatment</h1>
      <form method="post" id="myForm">
         <label for="taskname" style="font-size: 20px">Task name*:</label>
         <input type="text" name="taskname" id="taskname" />
         <label for="tasknumber" style="font-size: 20px">Task number*:</label>
         <input type="number" name="tasknumber" id="tasknumber" />
         <b><p style="display:inline"> * Cannot be null</p></b>
         <input type="button" value="Start" onclick="submitForm()">
      </form>
      <div id="responseArea"></div>
   </body>
</html>

【讨论】:

    猜你喜欢
    • 2021-12-27
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多