Python 在不是域根的URL上运行Flask应用程序
我正在将一个Flask应用程序从apache2和mod_wsgi环境移动到Nginx,但在让URL正常工作时遇到了问题 我希望我的应用程序的根页面出现在,例如,Python 在不是域根的URL上运行Flask应用程序,python,nginx,flask,gunicorn,wsgi,Python,Nginx,Flask,Gunicorn,Wsgi,我正在将一个Flask应用程序从apache2和mod_wsgi环境移动到Nginx,但在让URL正常工作时遇到了问题 我希望我的应用程序的根页面出现在,例如, My@app.route decorators例如是我的应用程序的根()的@app.route('/subpage'),以及像这样的子页面的@app.route('/subpage') 在apache下,这一切“刚刚工作”,我对url\u for()的调用生成了完成工作的url 现在我的url从url\u for()的形式是:href=
My@app.route decorators例如是我的应用程序的根(
)的@app.route('/subpage')
,以及像
这样的子页面的@app.route('/subpage')
在apache下,这一切“刚刚工作”,我对url\u for()
的调用生成了完成工作的url
现在我的url从url\u for()
的形式是:href=“/subpage”
,它将我发送到域根,
,而不是我想要的:href=“/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提供申请
根据目前的情况,访问
会将我带到Flask应用程序的根页面,但所有其他URL会将我带回到域级别:
我曾尝试将应用程序_ROOT设置为“/myapp”,但似乎没有效果。我做错了什么(可怕的)?在您的nginx配置中,您应该使用包含应用所在子路径的主机头进行代理传递:
location /myapp {
...
proxy_set_header Host $host/myapp;
...
}
那么在烧瓶里你有两个选择
选项A
为使用一个新的url\u,它实际上将主机头放在url前面。这将采用类似于/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\u:
app.jinja_env.globals['url_for'] = url_for
选项B
使用
的url\u中的\u外部
标志。这将使用完整路径呈现链接,如:http://www.example.com/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))
所以在你的flask应用程序中生成url的使用
url_for('index', _external=True)
尽管url\u for
提到了APPLICATION\u ROOT
,但它仅在没有当前请求上下文(即不在web服务器中)的情况下使用,因此在大多数情况下没有任何用处
实际的机制是通过wsgi变量SCRIPT\u 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/
或上游服务器所在的任何位置。这两个都是非常糟糕的解决方法,它们忽略了执行itA主机
的实际标准方法,例如,包含路径的头无效。