由CherryPy托管的Flask应用:OPTIONS返回404

时间:2018-01-25 05:59:52

标签: flask cherrypy flask-restful traefik flask-cors

我使用Flask和Flask-Restful创建了一个非常好的API。使用开发服务器一切正常。所有路线都在蓝图中,尽管我们在这里处理的特定路线不是Flask-Restful路线。这只是一个普通的Flask路线。

我也在使用Flask-CORS。

要部署,所有内容都是docker化的,我使用CherryPy作为WSGI主机。所以CherryPy应用程序在容器中托管Flask应用程序。 我在另一个容器中使用Traefik作为反向代理。

如果我通过粘贴网址在Chrome中发出以下请求,则GET请求有效:

https://api.my-app.new/api/admin/user?_end=10&_order=DESC&_sort=id&_start=0

但是,如果我attemtp从React应用程序发出相同的GET请求,则会发出OPTIONS预检请求,并且失败时会显示404。 我已经在PyCharm中尽可能地跟踪了它,问题似乎出现在Flask的app.py中的以下代码中:

def preprocess_request(self):
    bp = _request_ctx_stack.top.request.blueprint

基本上,找不到蓝图。

在这个卷曲调用中可以看到实际发送的内容:

curl 'https://api.my-app.new/api/admin/user?_end=10&_order=DESC&_sort=id&_start=0' \
     -X OPTIONS -H 'access-control-request-method: GET' -H 'origin: https://admin.my-app.new' \
     -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' \
     -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' \
     -H 'accept: */*' -H 'referer: https://admin.my-app.new/' -H 'authority: api.my-app.new' \
     -H 'access-control-request-headers: authorization,content-type' --compressed

如果我打印出Flask-app收到的标题(在@ app.before_request中),我会得到以下内容:

[2018-01-25 04:31:48,438] INFO - X-Forwarded-Server: cb5d56692c6d
Referer: https://admin.my-app.new/
Accept-Language: en-US,en;q=0.9
Origin: https://admin.my-app.new
X-Real-Ip: 172.19.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Access-Control-Request-Headers: authorization,content-type
X-Forwarded-Proto: https
Host: api.my-app.new
Accept: */*
Access-Control-Request-Method: GET
X-Forwarded-Host: api.my-app.new
X-Forwarded-For: 172.19.0.1
X-Forwarded-Port: 443
Accept-Encoding: gzip, deflate, br

[2018-01-25 04:31:48,440] INFO - Error 404:/api/admin/user?_end=10&_order=DESC&_sort=id&_start=0: 404 Not Found: The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again. ("/app/app/routes.py:87")

现在,如果我在没有traefik反向代理的情况下运行的应用程序发出相同的请求,它就可以了。唯一不同的是卷曲 请求是我使用的是http,而不是https。

以下是Flask在这种情况下收到的标题:

[2018-01-24 21:43:43,199] INFO - Referer: https://admin.my-app.new/
Origin: https://admin.my-app.new
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Authority: api.my-app.new
Access-Control-Request-Headers: authorization,content-type
Host: api.my-app.new:8000
Accept: */*
Access-Control-Request-Method: GET
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br

[24/Jan/2018 21:43:43] "OPTIONS /api/admin/user?_end=10&_order=DESC&_sort=id&_start=0 HTTP/1.1" 200 -

我认为标题有问题或者让Flask感到困惑。我看到2014年的另一篇文章提到需要SERVER_NAME,但这没有帮助。

最后,我最初使用NGinx作为预备代理,并且已经完成了所有工作。其中一件事 很难与NGinx合作的是重定向和OPTION请求。疯狂地追逐各种博客之后,我确实得到了它 帖子,但是当我回想起它时,我注意到了一个奇怪的事情:我在nginx.conf中编写脚本 为所有OPTIONS请求自动返回200!

知道为什么OPTION请求失败了吗?

1 个答案:

答案 0 :(得分:1)

正如webKnjaZ所说:"这是一个错误。"

深入挖掘后,我发现Flask获取GET请求的URL与OPTIONS请求不同的问题,如果CherryPy被删除,问题就会消失。这让我想到了这个完全描述我情况的CherryPy问题。

https://github.com/cherrypy/cherrypy/issues/1662

作者注意到从CherryPy 11转到12(我在13.x时)时出现了错误,所以我尝试降级到11.0.0并修复了它。