Axios Post没有等待React,因此永远不会进入,然后

cetgtptt  于 2023-01-09  发布在  iOS
关注(0)|答案(1)|浏览(134)

我正在使用React和FastAPI制作一个简单的登录身份验证应用程序。我的Axios Post请求最初的工作方式与完全相同的代码一样,只是我稍微更改了UI。
基本上react会发送一个post请求到我的服务器,然后如果它通过了验证,它会用一个会话令牌来响应。这以前是有效的。我不知道为什么它不再有效了。
我尝试只返回一个简单的{“token”:“hello”},然后它被正确地存储,所以我假设它与它所花费的时间有关。基本上react不会等待POST请求发送响应,而是继续前进并返回html。日志显示fastapi正在返回正确的内容。它进入.then,但没有进入它的function (response)部分。
登录页面的React代码

import { useNavigate } from "react-router";
import { fetchToken, setToken } from "./Auth";
import { useState } from "react";
import axios from "axios";

export default async function Login() {
  const navigate = useNavigate();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  //check to see if the fields are not empty
  const login = () => {
    console.log(email, password);
    if ((email === "") & (password === "")) {
      return;
    } else {
      axios
        .post("http://localhost:8000/login", {
          email: email,
          password: password,
        })
        .then(function (response) {
          console.log(response.data.token, "response.data.token");
          if (response.data.token) {
            setToken(response.data.token);
            navigate("/profile");
          }
        })
        .catch(function (error) {
          console.log(error, "error");
        });
    }
  };
  
  return (
    <div>
      {fetchToken() ? (
        <p>you are logged in</p>
      ) : (
    <form>
      <h3>Sign In</h3>
      <div className="mb-3">
        <label>Email address</label>
        <input
          type="email"
          className="form-control"
          placeholder="Enter email"
          onChange={(e) => setEmail(e.target.value)}
        />
      </div>

      <div className="mb-3">
        <label>Password</label>
        <input
          type="password"
          className="form-control"
          placeholder="Enter password"
          onChange={(e) => setPassword(e.target.value)}
        />
      </div>

      <div className="d-grid">
        <button type="submit" className="btn btn-primary" onClick={login}>
          Submit
        </button>
      </div>

      <p className="forgot-password text-right">
          Not registered <a href="/sign-up">sign up?</a>
      </p>
      
    </form>
    )}
    </div>
  );
}

后端FastAPI代码

from fastapi import FastAPI
import jwt
from pydantic import BaseModel, Field
from fastapi.encoders import jsonable_encoder
from fastapi.middleware.cors import CORSMiddleware
from pymongo import MongoClient
from bson import ObjectId
import certifi

# imported for mongo maybe
from fastapi import FastAPI, Body, HTTPException, status
from fastapi.responses import Response, JSONResponse

SECERT_KEY = "YOUR_FAST_API_SECRET_KEY"
ALGORITHM  = "HS256"
ACCESS_TOKEN_EXPIRES_MINUTES = 800

test_user = {
   "email": "temitope",
    "password": "temipassword",
}

url = "uri"
app = FastAPI()
client = MongoClient(url, tlsCAFile=certifi.where())
db = client.test

origins = {
    "http://localhost",
    "http://localhost:3000",
}

app.add_middleware(
   CORSMiddleware,
    allow_origins = origins,
    allow_credentials =True,
    allow_methods = ["*"],
    allow_headers= ["*"],
)

class LoginItem(BaseModel):
    email: str
    password: str

    @app.get("/")
    def read_root():
        return {"Hello": "World"}

    class Config:
        schema_extra = {
            "example": {
                "email": "devang@hello",
                "password": "encrypted"
            }
        }

class PyObjectId(ObjectId):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if not ObjectId.is_valid(v):
            raise ValueError("Invalid objectid")
        return ObjectId(v)

    @classmethod
    def __modify_schema__(cls, field_schema):
        field_schema.update(type="string")

class UserModel(BaseModel):
    id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
    firstName: str = Field(...)
    lastName: str = Field(...)
    email: str = Field(...)
    password: str = Field(...)

    class Config:
        allow_population_by_field_name = True
        arbitrary_types_allowed = True
        json_encoders = {ObjectId: str}
        schema_extra = {
            "example": {
                "firstName": "Devang",
                "lastName": "Agrawal",
                "email": "devang@hello",
                "password": "encrypted"
            }
        }

#function to encode the user
def get_jwt(user:UserModel):

    #jsonify the user and delete the firstName and lastName and _id
    data = jsonable_encoder(user)
    print(data)
    del data['firstName']
    del data['lastName']
    del data['_id']
    print(data)
    return jwt.encode(data, SECERT_KEY, algorithm=ALGORITHM)

#function to retrieve user with the given encoded jwt token
def get_user(encoded_jwt):
    #look at all the users in the database
    users = db["users"].find()

    #check if the user exists in the database
    for user in users:
        if user['encoded_jwt'] == encoded_jwt:
            return user

@app.post("/login")
async def user_login(loginitem:LoginItem):

    #look at all the users in the database
    data = jsonable_encoder(loginitem)
    # return {"token": data["email"]}
    print(f"{data} is the data")

    #encode the user
    encoded_jwt = jwt.encode(data, SECERT_KEY, algorithm=ALGORITHM)

    #check if the user exists in the database
    if get_user(encoded_jwt) != None:
        print("success")
        return {"token": encoded_jwt}

    print("failed")
    return {"message": "login failed"}

@app.post("/add", response_description="Add new user", response_model=UserModel)
async def create_user(user: UserModel = Body(...)):

    #jsonify the userx
    user = jsonable_encoder(user)

    #encode the user and add it to the user object
    user['encoded_jwt'] = get_jwt(user)
    del user['password']
    print(user)

    #add the user to the database
    new_user = db["users"].insert_one(user)
    created_user = db["users"].find_one({"_id": new_user.inserted_id})

    #return success message
    return JSONResponse(status_code=status.HTTP_201_CREATED, content=created_user)

有没有人知道如何确保用axios post正确处理响应。我也试过异步和等待,同时设置随机超时,但什么都不起作用。

ewm0tg9j

ewm0tg9j1#

尝试移动formonSubmit事件中的login函数:

<form onSubmit={login}>

submit按钮上取下onClick

<button type="submit" className="btn btn-primary">...</button>

并在执行前调用e.preventDefault()

const login = (e) => {
  e.preventDefault();

  console.log(email, password);
  if ((email === '') & (password === '')) {
    return;
  }
  
  axios
    .post('http://localhost:8000/login', { email, password })
    .then(function (response) {
      console.log(response.data.token, 'response.data.token');
      if (response.data.token) {
        setToken(response.data.token);
        navigate('/profile');
      }
    })
    .catch(function (error) {
      console.log(error, 'error');
    });
  }
};

相关问题