我正在将一个Flask应用程序从apache2和mod_wsgi环境移动到Nginx,并且在使url正常工作时遇到问题。
我希望我的应用的根页面显示在,例如http://example.org/myapp/
我的@ app.route装饰者是例如@app.route('/')
代表我的应用的根(http://example.org/myapp
)和@app.route('/subpage')
代表http://example.org/myapp/subpage
等子页面。
在apache下,所有“正常工作”,我对url_for()
的调用产生了完成工作的URL。
现在,来自url_for()
的我的网址格式为:href="/subpage"
,它将我发送到域根,http://example.org/subpage
而不是我想要的:href="./subpage"
,其中会带我去http://example.org/myapp/subpage
。
对于它的价值,我的Nginx配置中的相关部分是:
location /myapp/ {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_pass http://127.0.0.1:8001/;
}
我正在使用gunicorn服务该应用程序。
根据现状,访问http://example.org/myapp/
会将我带到Flask应用程序的根页面,但所有其他网址都会将我带回域级别:http://example.org/subpage
。
我尝试将APPLICATION_ROOT设置为“/ myapp”,但似乎没有效果。我在做什么(可怕)错了?
答案 0 :(得分:2)
我知道这是一个老问题,但我遇到了同样的问题,我想要的东西比EricD的答案更好。
在您的nginx配置中,您应该使用包含应用所在的子路径的HOST标头进行代理传递:
location /myapp {
...
proxy_set_header Host $host/myapp;
...
}
然后在Flask中你有两个选择
选项A
使用实际将HOST标头添加到网址的新url_for
。这将采用/mypage
之类的路径并将其转换为/myapp/mypage
from urllib.parse import urlparse
from flask import request, url_for as _url_for
def url_with_host(path):
return '/'.join((urlparse(request.host_url).path.rstrip('/'), path.lstrip('/')))
def url_for(*args, **kwargs):
if kwargs.get('_external') is True:
return _url_for(*args, **kwargs)
else:
return url_with_host(_url_for(*args, **kwargs))
您甚至可以使用:
更新Jinjaurl_for
app.jinja_env.globals['url_for'] = url_for
选项B
使用_external
中的url_for
标记。这将使链接呈现完整路径,如:http://www.example.com/myapp/mypage
所以在你的烧瓶app中使用
生成urlurl_for('index', _external=True)
答案 1 :(得分:1)
尽管 url_for
提到了 APPLICATION_ROOT
,但它仅在没有当前请求上下文(即不在 Web 服务器中)时才使用,因此大部分时间根本没有用。
实际机制是通过 wsgi 变量 SCRIPT_NAME
。使用 gunicorn
,您可以通过以下几种方式在命令行上传递它:
gunicorn --env SCRIPT_NAME=/myapp app:app
SCRIPT_NAME=/myapp gunicorn app:app
在某些 wsgi 系统(例如 mod_wsgi
)中,它也可以作为请求标头传递。
为此,您需要不要在反向代理上删除路径。 nginx 配置应该是:
location /myapp {
proxy_pass http://localhost:8000/myapp/;
proxy_set_header Host $host;
proxy_redirect off;
}
或 http://unix:/run/gunicorn.sock/myapp/
或上游服务器所在的任何位置。