Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在不是域根的URL上运行Flask应用程序_Python_Nginx_Flask_Gunicorn_Wsgi - Fatal编程技术网

Python 在不是域根的URL上运行Flask应用程序

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=

我正在将一个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=“/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))
您甚至可以使用以下方法更新
的Jinja
url\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
主机
的实际标准方法,例如,包含路径的头无效。