我有一个FastAPI应用程序在我的本地机器上运行,其URL为:http://localhost:8000
,使用以下Python代码:
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"*"
'''
"http://localhost:8000/add_points/",
"http://localhost:8000/check_points/",
"http://localhost:8000/check_item_points/",
"http://localhost:8000/redeem_points/"
'''
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
users = {"matt": 0}
items = {"ticket": 7}
class User(BaseModel):
name: str
points: float
item: str
class AddTransaction(BaseModel):
name: str
points: float
class UserPoints(BaseModel): # anything that extnds this base model is a pyantic model
name: str
points: float
class Item(BaseModel):
name: str
points: float
# -----Post Requests-----
@app.post("/add_points/")
def add_points(add_transaction: AddTransaction):
global users
user_id = add_transaction.name
points = add_transaction.points
users[user_id] = users.get(user_id, 0) + points
return users[user_id]
@app.post("/check_points/")
def check_points(user_points: UserPoints):
global users
user_id = user_points.name
points = user_points.points
return users[user_id], points
@app.post("/check_item_points/")
def check_item_points(item: Item):
global items
item_id = item.name
points = item.points
return item[item_id], points
@app.post("/redeem_points/") # user spends points (they lose points) gain an item
def redeem_points(add_transaction: AddTransaction, user_points: UserPoints, item: Item, user: User):
global users
global items
user_id = add_transaction.name
user_points = user_points.points
item_points = item.points
item_pre = item.name
item_post = user.item
if user_points >= item_points:
user_points == user_points - item_points
item_post == item_pre
return users[user_id], users[user_points], users[item_post]
else:
return "insufficient funds"
# -----Get Requests-----
@app.get("/")
def read_root():
return {"Hello": "World"}
# -----Put Requests-----
""""
@app.put("/items/{item_id}")
def update_item(item_id: int, item:Item):
return {"item_name": item.name, "item_id": item_id}
"""
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
我还有一个HTML文件,里面有JS脚本,只需单击一个按钮就可以向http://localhost:8000/add_points/
发送一个POST
请求。代码如下:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<body>
<br><br><br><span style="text-align: center;"><button id="send">Send Request</button></span>
</body>
<script>
$("#send").on("click", evt => {
$.post("http://localhost:8000/add_points/",
{
name: "string",
points: 5.0
},
function(data, status){
alert("Data: " + data + "\nStatus: " + status);
});
});
</script>
</html>
然而,当我尝试发送POST
请求时,我在PyCharm中得到以下错误:
INFO:127.0.0.1:49413-“OPTIONS /add_points/ HTTP/1.1”400错误请求
INFO:127.0.0.1:49413-“POST /add_points/ HTTP/1.1”422 Unprocessable Entity
我知道这些错误中至少有一个是由CORS政策限制引起的,然而,这个项目是针对移动的电话用户的,他们不应该安装任何浏览器扩展来覆盖政策。任何关于如何修复这些错误的建议将不胜感激!
编辑更新:
const url = new URL('localhost:8000/add_points/');
$("#send").on("click", evt => { fetch(url,
{
method: 'POST',
headers: {'Accept': 'application/json', 'Content-Type': 'application/json'},
body: JSON.stringify({"name":"John", "points":50.0})
}).then().catch((error) => { console.log(error.message); }); });
我仍然收到400 Bad Request
错误。
1条答案
按热度按时间ddrv8njm1#
如果您正在从Jinja2 template或
HTMLResponse
访问前端-这似乎是这样的,正如您的应用正在侦听的port
以及您在CORSMiddleware
中定义的origins
所示-您不需要为您的应用启用CORS。如this answer和this answer中所述,只有当protocol
、domain
和port
全部匹配时,两个对象才具有相同的原点**。请注意,
localhost
和127.0.0.1
被认为是不同的来源。因此,如果你从浏览器访问你的前端(通过在地址栏中键入URL)在http://127.0.0.1:8000/
,那么你的异步JS请求(例如使用fetch
)应该使用该域;例如:不是
反之亦然。您可以始终使用相对路径来请求
fetch
(如下所示),因此,无论您使用哪个域名(localhost
或127.0.0.1
)从浏览器访问前端,您的应用都将正常工作。工作示例:
请参阅相关答案here、here和here。
app.py
模板/index.html