422 使用 ReactJs 将表单数据发送到 FastAPI 后端时出现无法处理的实体

问题描述 投票:0回答:1

我不断收到

422 Unprocessable Entity
以及那些缺失的字段:

{"detail":[{"type":"missing","loc":["body","username"],"msg":"Field required","input":null},{"type":"missing","loc":["body","password"],"msg":"Field required","input":null}]}

我尝试了所有可能的方法,但错误仍然存在

这是我的前端代码:

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const navigate = useNavigate();

  const handleLogin = async (e) => {
    e.preventDefault();
    
    const formData = new URLSearchParams();
    formData.append('username', email); // Assuming the backend expects 'username'
    formData.append('password', password);

    try {
      const response = await fetch('http://localhost:8000/token', {
        method: 'POST',
        body: formData,
      });

      if (!response.ok) {
        throw new Error('Login failed');
      }

这是在后端:

@fastapi_router.post("/token", response_model=Token)
async def login_for_access_token(
    username: Annotated[str, Form()],
    password: Annotated[str, Form()],
    db: AsyncSession = Depends(database.get_db)
):
    user = await auth.authenticate_user(db, username, password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=envs.access_token_expire_minutes)
    access_token = auth.create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    logger.info(f"Access Token: {access_token}")
    return {"access_token": access_token, "token_type": "bearer"}

如有任何帮助,我们将不胜感激。

javascript python reactjs fastapi http-status-code-422
1个回答
0
投票

这是一个关于如何在前端使用 JavaScript Fetch API 将

Form
数据提交到 FastAPI 后端的工作示例。

工作示例

app.py

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

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


@app.post("/submit")
def submit(username: str = Form(...), password: str = Form(...)):
    return {"username": username, "password": password}


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

模板/index.html

<!DOCTYPE html>
<html>
   <body>
      <input type="button" value="Submit" onclick="send()">
      <p id="resp"></p>
      <script>
         function send() {
           var resp = document.getElementById("resp");
           var formData = new FormData();
           formData.append("username", "test");
           formData.append("password", "pass");
          
           fetch('/submit', {
                 method: 'POST',
                 body: formData,
              })
              .then(response => response.json())
              .then(data => {
                 resp.innerHTML = JSON.stringify(data); // data is a JSON object
              })
              .catch(error => {
                 console.error(error);
              });
         }  
      </script>
   </body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.