Django没有从nginx获取脚本名称头

时间:2015-10-10 06:29:13

标签: django nginx

我顺便使用Django 1.8。

我正在尝试使用相同的域/子域但不同的URL部署多个Django应用程序,因此我使用SCRIPT_NAME标头。

我的Nginx配置:

location /myapp/ {
    proxy_pass http://127.0.0.1:8000/;
    proxy_set_header SCRIPT_NAME /myapp;
}

网站正在加载此conf但请求。 META ['SCRIPT_NAME']是空的,当我悬停任何链接时,它们在网址中显示没有'myapp'。

任何帮助?

2 个答案:

答案 0 :(得分:1)

我可以通过以下代码段的一些帮助部分解决此问题:http://flask.pocoo.org/snippets/35/

location /myapp {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Scheme $scheme;
    proxy_set_header X-Script-Name /myapp;
    }

然后我在myapp文件夹中创建了一个wsgi.py文件:

from django.core.wsgi import get_wsgi_application

_application = get_wsgi_application()

def application(environ, start_response):
    script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
    if script_name:
        environ['SCRIPT_NAME'] = script_name
        path_info = environ['PATH_INFO']
        if path_info.startswith(script_name):
            environ['PATH_INFO'] = path_info[len(script_name):]

    scheme = environ.get('HTTP_X_SCHEME', '')
    if scheme:
        environ['wsgi.url_scheme'] = scheme
    return _application(environ, start_response)

我还必须从使用

切换
python manage.py runserver 0.0.0.0:8000

用于提供使用uWSGI的应用程序。为此,我按照Setting up Django and your web server with uWSGI and nginx的说明进行操作 但基本上归结为

pip install uwsgi

然后用

提供Django应用程序
uwsgi --http :8000 --module myapp.wsgi

编辑:目前这对staticmedia资产不起作用。请参阅此打开的门票:https://code.djangoproject.com/ticket/25598

答案 1 :(得分:0)

我在所有搜索中都没有找到答案,所以在这里:

  1. 这仅在 Django 3.1.6 中正确实现,因此 1.8 不起作用。
  2. proxy_pass http://127.0.0.1:8000/ 是错误的,您需要 proxy_pass http://127.0.0.1:8000(没有尾部反斜杠)才能将 /myapp 保留在 URL 路径的开头。 Django 期望其请求以 SCRIPT_NAME 标头的值开始,并在您的应用看到它之前将其剥离。对于任何不是这样开头的 URL,Django 将返回错误。
  3. 如果您的 settings.pySTATIC_URL 定义为像 /static/ 这样的绝对路径,Django 不会在它前面加上您的脚本名称。使用像 static/ 这样的相对路径。
  4. 如果中间有任何其他代理,请确保它们没有丢弃 STATIC_FILES 标头。例如,如果中间有另一个 nginx,则需要确保 server 块包含行 underscores_in_headers on;
  5. LOGIN_REDIRECT_URL 这样的设置没有预先设置(并且你不能使用相对路径技巧,因为这会做一些不同的事情),所以你可以用一行来捏造它:proxy_redirect / /myapp/;,但是大多数重定向都是预先设置的,因此您还需要在此之前添加一行:proxy_redirect /myapp/ /myapp/;。当然,如果 /myapp/myapp 实际上是有效路径,则此技术将不起作用。
  6. 如果您想静态地提供静态文件,请记住为此包含一个位置块。

所以你的 nginx 块应该看起来像这样:

location /myapp/ {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header SCRIPT_NAME /myapp;
    proxy_redirect /myapp/ /myapp/;
    proxy_redirect / /myapp/;
    location /myapp/static/ {
        root /var/www; # files are deployed to /var/www/myapp/static
    }
}

并在settings.py中:

STATIC_URL=`static/`

并在requirements.txt中:

Django==3.1.6

真是一场噩梦。有人有更好的想法吗?