FastAPI 拒绝来自 javascript 代码的 POST 请求,但不拒绝来自第 3 方请求应用程序的 POST 请求(失眠)

发布于 2025-01-12 18:17:50 字数 1792 浏览 2 评论 0原文

当我使用 insomnia 发送帖子请求时得到 200 代码,一切工作正常,但是当我通过 javascript 发送 fetch 请求时,我收到 405“方法不允许错误”,即使我已经允许来自服务器端的 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 ) ) })

错误

在此处输入图像描述

我应该怎么做才能解决这个问题错误?
提前致谢。

When I use insomnia to send a post request I get a 200 code and everything works just fine, but when I send a fetch request through javascript, I get a 405 'method not allowed error', even though I've allowed post requests from the server side.
(Server side code uses python).

Server side code

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 code

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 ) ) })

The error

enter image description here

What should I do to get around this error?
Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陪你到最终 2025-01-19 18:17:50

首先,您的代码似乎工作得很好。在测试过程中(本地)唯一需要更改的部分是 fetch 中的 URL,从 /post/submit_post 到(例如)http://127.0.0.1:8000/post /submit_post,但我假设您已经使用指向您的应用程序的域名进行了更改。

不允许使用 405 方法 状态码与 CORS 无关。如果 allow_methods 列表中未包含 POST,则响应状态代码将为 400 Bad Request(您可以尝试将其从列表中删除来测试)。从上面的参考资料来看:

超文本传输​​协议 (HTTP) 405 Method Not Allowed 响应
状态码表示服务器知道请求方法,但是
目标资源不支持此方法

服务器必须在 405 状态代码中生成 Allow 标头字段
回复。该字段必须包含目标方法的列表
资源目前支持。

因此,405 状态代码表示服务器已接收并识别 POST 请求,但服务器已拒绝该特定 该特定端点的 HTTP 方法。因此,我建议您确保您正在运行的版本中端点的装饰器定义为 @app.post,并且没有其他端点使用 具有相同的路径>@app.get。此外,请确保端点内没有发生任何无意的重定向,因为这可能是导致该响应状态代码的另一个可能原因。为了将来参考,当从 POST 重定向到 GET 请求时,响应状态代码必须更改为 303,如下所示 此处。另外,您可以尝试使用通配符 * 允许所有 HTTP 方法(即 allow_methods=['*'])并查看其工作原理(即使它不应该)与此有关)。最后,这也可能与您运行应用程序的托管服务的配置有关;因此,研究一下也可能是件好事。

To start with, your code seems to be working just fine. The only part that had to be changed during testing it (locally) was the URL in fetch from /post/submit_post to (for instance) http://127.0.0.1:8000/post/submit_post, but I am assuming you already changed that using the domain name pointing to your app.

The 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 (you could try removing it from the list to test it). From the reference above:

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.

Thus, the 405 status code indicates that the POST request has been received and recognized by the server, but the server has rejected that specific 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 here. Also, you could try allowing all HTTP methods with the wildcard * (i.e., allow_methods=['*']) and see how that works (even though it shouldn't be related to that). Lastly, this could also be related to the configurations of the hosting service you are running the application; thus, might be good to have a look into that as well.

变身佩奇 2025-01-19 18:17:50

这是一个老问题,此处进行了描述。您的请求中需要 Access-Control-Request-Method: POST 标头。

It's and old issue, described here. You need Access-Control-Request-Method: POST header in your request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文