FastAPI 和 SlowAPI 无法处理 Ajax 和 getJSON 请求 - python

FastAPI and SlowAPI not working on Ajax and getJSON request - python

我有问题。当我正确地从浏览器或邮递员发出太多请求时,API (slowapi) 会阻止我,因为我已正确设置,但如果我通过 AJAX 和 jquery 的 $ 发出请求。 getJSON,APIs 不要阻止我。我该如何解决? 我的代码(摘自完整代码):

from fastapi import FastAPI, Request, Response, status
from fastapi.middleware.cors import CORSMiddleware
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from slowapi.middleware import SlowAPIMiddleware
limiter = Limiter(key_func=get_remote_address, default_limits=["2/5seconds"])
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.add_middleware(SlowAPIMiddleware)

@app.get('/schools/{regione}/{provincia}/{comune}')
def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):
    if(request.headers.get("Provider") == "Test-User-Provider"):
        return {"message": "OK", "status": "success", "code": 200}

    else:
        response.status_code = status.HTTP_400_BAD_REQUEST
        return {"message": "Provider not found", "status": "error", "code": 400}

浏览器结果(工作):

{"error":"Rate limit exceeded: 2 per 5 second"}

Jquery 代码(无效):

$.getJSON(apiURL+"/schools/Test/Test/Test", function(data) {
        console.log(data)
});

显然 jquery 我试图每秒发出很多请求 控制台浏览器结果(不限!):

{message: '...', status: 'success', code: 200}

万分感谢。

更新 通过 jquery 我尝试向其他路径发出请求并且它是正确的速率限制。如果我向这条路径发出请求 /schools/{region}/{province}/{municipality} 速率限制不起作用

更新 2

我参考了更新和测试的代码。当我向路径 /testpath /{region} 发送请求时,它被正确地限制了速率。相反,如果我向某些子路径发送请求(/schools/{region}/{province}/{municipality} 它不受速率限制。

jQuery代码与上面列出的相同

from fastapi import FastAPI, Request, Response, status
from fastapi.middleware.cors import CORSMiddleware
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from slowapi.middleware import SlowAPIMiddleware

limiter = Limiter(key_func=get_remote_address, default_limits=["2/5seconds"])
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

origins = ["http://127.0.0.1/", "http://localhost", "http://192.168.1.75"] ## CORS

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.add_middleware(SlowAPIMiddleware) ## Rate-limit all request

@app.get('/schools/{regione}/{provincia}/{comune}')
def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):
        return {"message": 'No schools found!', "status": 'error', "code": 200} ## Or if found return schools informations

@app.get('/testpath/{regione}') ## Works with one path. If I add "provincia" and "comune" non work
def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):
        return {"message": 'No schools found!', "status": 'error', "code": 200} ## Or if found return schools informations

如果我使用学校路径:

如果我使用测试路径,它是正确的速率限制:

测试了您的代码并且工作正常,只要您在 getJSON() 方法中将右双引号 替换为直双引号 "

$.getJSON(apiURL + "/security/validate_token", function(data) {
        console.log(data)
});

上面你写了“状态响应是个性化的,我自己决定的”。因此,如果您仍然收到 {message: '...', status: 'success', code: 200} 响应,我建议您尝试返回一个简单的消息,例如 return {"status": "success"},然后看看它是否按预期工作。如果不是,则可能是您的自定义响应中未以正确的方式实施。

更新

下面应该按预期工作。如果没有,那么问题可能出在您的问题中未包含的代码中的其他地方。我还建议将它作为 tempalte 添加到您的应用程序中,因为从您发布的错误来看,您似乎收到了 Cross-Origin 警告。

<!DOCTYPE html>
<html>
   <head>
      <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
      <script type="text/javascript" >
         function on_click(){
            $.getJSON("http://127.0.0.1:8000/schools/Test/Test/Test", function(data) {
                 console.log(data)
            });
         }
      </script>
   </head>
   <body>
      <input type="button" value="submit" onclick="on_click()">
   </body>
</html>