FastAPI 拒绝来自 javascript 代码的 POST 请求,而不是来自第 3 方请求应用程序的请求(失眠)
FastAPI rejecting POST request from javascript code but not from a 3rd party request application (insomnia)
当我使用 insomnia 发送一个 post 请求时,我得到一个 200 代码并且一切正常,但是当我通过 javascript 发送一个获取请求时,我得到一个405 'method not allowed error',即使我已经允许来自服务器端的 post 请求。
(服务器端代码使用 python)。
服务器端代码
from pydantic import BaseModel
from typing import Optional
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = ["*"]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["POST", "GET"],
allow_headers=["*"],
)
class data_format(BaseModel):
comment_id : int
username : str
comment_body : Optional[str] = None
@app.post('/post/submit_post')
async def sumbit_post(somename_3: data_format):
comment_id = somename_3.comment_id
username = somename_3.username
comment_body = somename_3.comment_body
# add_table_data(comment_id, username, comment_body) //Unrelated code
return {
'Response': 'Submission received',
'Data' : somename_3
}
JS代码
var payload = {
"comment_id" : 4,
"username" : "user4",
"comment_body": "comment_4"
};
fetch("/post/submit_post",
{
method: "POST",
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })
错误
我应该怎么做才能解决这个错误?
提前致谢。
这是一个老问题,如 here 所述。您的请求中需要 Access-Control-Request-Method: POST
header。
首先,您的代码似乎运行良好。在测试期间(本地)必须更改的唯一部分是从 /post/submit_post
到(例如)http://127.0.0.1:8000/post/submit_post
中获取的 URL,但我假设您已经使用指向您的应用程序的域名。
405 Method Not Allowed
status code is not related to CORS. If POST
was not included in the allow_methods
list, the response status code would be 400 Bad Request
(您可以尝试将其从列表中删除以进行测试)。来自上面的参考:
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed
response
status code indicates that the server knows the request method, but
the target resource doesn't support this method.
The server must generate an Allow
header field in a 405 status code
response. The field must contain a list of methods that the target
resource currently supports.
因此,405状态码表示POST
请求已经被服务器接收并识别,但是服务器拒绝了那个特定的HTTP method for that particular endpoint. Therefore, I would suggest you make sure that the decorator of the endpoint in the version you are running is defined as @app.post
, as well as there is no other endpoint with the same path using @app.get
. Additionally, make sure there is no any unintentional redirect
happening inside the endpoint, as that would be another possible cause of that response status code. For future reference, when redirecting from a POST
to GET
request, the response status code has to change to 303
, as shown 。此外,您可以尝试使用通配符 *
(即 allow_methods=['*']
)允许所有 HTTP 方法,看看它是如何工作的(即使它不应该与此相关)。最后,这也可能与您是 运行 应用程序的托管服务的配置有关;因此,也可以看看它。
当我使用 insomnia 发送一个 post 请求时,我得到一个 200 代码并且一切正常,但是当我通过 javascript 发送一个获取请求时,我得到一个405 'method not allowed error',即使我已经允许来自服务器端的 post 请求。 (服务器端代码使用 python)。
服务器端代码
from pydantic import BaseModel
from typing import Optional
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = ["*"]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["POST", "GET"],
allow_headers=["*"],
)
class data_format(BaseModel):
comment_id : int
username : str
comment_body : Optional[str] = None
@app.post('/post/submit_post')
async def sumbit_post(somename_3: data_format):
comment_id = somename_3.comment_id
username = somename_3.username
comment_body = somename_3.comment_body
# add_table_data(comment_id, username, comment_body) //Unrelated code
return {
'Response': 'Submission received',
'Data' : somename_3
}
JS代码
var payload = {
"comment_id" : 4,
"username" : "user4",
"comment_body": "comment_4"
};
fetch("/post/submit_post",
{
method: "POST",
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })
错误
我应该怎么做才能解决这个错误?
提前致谢。
这是一个老问题,如 here 所述。您的请求中需要 Access-Control-Request-Method: POST
header。
首先,您的代码似乎运行良好。在测试期间(本地)必须更改的唯一部分是从 /post/submit_post
到(例如)http://127.0.0.1:8000/post/submit_post
中获取的 URL,但我假设您已经使用指向您的应用程序的域名。
405 Method Not Allowed
status code is not related to CORS. If POST
was not included in the allow_methods
list, the response status code would be 400 Bad Request
(您可以尝试将其从列表中删除以进行测试)。来自上面的参考:
The HyperText Transfer Protocol (HTTP)
405 Method Not Allowed
response status code indicates that the server knows the request method, but the target resource doesn't support this method.The server must generate an
Allow
header field in a 405 status code response. The field must contain a list of methods that the target resource currently supports.
因此,405状态码表示POST
请求已经被服务器接收并识别,但是服务器拒绝了那个特定的HTTP method for that particular endpoint. Therefore, I would suggest you make sure that the decorator of the endpoint in the version you are running is defined as @app.post
, as well as there is no other endpoint with the same path using @app.get
. Additionally, make sure there is no any unintentional redirect
happening inside the endpoint, as that would be another possible cause of that response status code. For future reference, when redirecting from a POST
to GET
request, the response status code has to change to 303
, as shown *
(即 allow_methods=['*']
)允许所有 HTTP 方法,看看它是如何工作的(即使它不应该与此相关)。最后,这也可能与您是 运行 应用程序的托管服务的配置有关;因此,也可以看看它。