Назад | Перейти на главную страницу

Сохранять заголовки http из Django с помощью NGINX и Gunicorn

Я устанавливаю некоторые не кэширующие заголовки в промежуточном программном обеспечении Django для управления кешированием запроса xhr. В основном потому, что IE сильно кеширует запросы ajax.

class NeverCacheXhrMiddleware(object):
    """
    sets no-cache headers for all xhr requests
    xhr requests must send the HTTP_X_REQUESTED_WITH header to 
    be identified correctly as a xhr request using .is_ajax()
    see: http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers
    """
    def process_response(self, request, response):
        if request.is_ajax():
            #add_never_cache_headers(response)
            #patch_cache_control(response, no_cache=True)
            response['Cache-Control'] = 'no-cache, no-store, must-revalidate'
            response['Pragma'] = 'no-cache'
            response['Expires'] = '0'
        return response

Это отлично работает, когда я развернул свое приложение, используя только Gunicorn в среде разработки. В производственной среде мы также запускаем NGINX перед Gunicorn, и кажется, что NGINX перезаписывает заголовки, установленные Django.

Посмотрите эти снимки экрана, чтобы увидеть, как меняются заголовки:

DEV Env .:

PROD Env. с NGINX:

Есть идеи, что изменить в конфигурации NGINX, чтобы NGINX передавал заголовки, установленные Django?

nginx conf. выглядит так:

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    sendfile        on;

    keepalive_timeout  65;

    include /path/to/sub_conf/*.conf;
}

Конфигурация сервера nginx. включен через sub conf:

server {
    listen       80;
    server_name  localhost1;

location / {
    proxy_pass http://127.0.0.1:8000;
    }
}

Видимо вы можете установить proxy_ignore_headers чтобы Nginx не изменял ваши заголовки.

proxy_ignore_headers Cache-Control Expires Pragma;

что может быть самым простым способом исправить это. То, что вы видите, может быть вызвано этой функцией в Nginx:

Change: now nginx does not cache by default backend responses, if they have a "Set-Cookie" header line.

Предположительно, они не сделали этого без какой-либо причины, но я не могу объяснить, почему эта функция была реализована.

Однако, если вы пытаетесь принудительно отключить все кеширование из-за того, что «IE сильно кэширует запрос ajax», у вас может быть лучшее решение, просто добавив уникальный номер к каждому запросу Ajax, что является более устойчивым способом заставить клиентов не кешировать ответы.

Проблема заключалась не в том, что nginx не передавал заголовки, установленные в исходном коде django, а в том, что nginx удалял все клиентские заголовки с подчеркиванием в них.

Поскольку Django ищет HTTP_X_REQUESTED_WITH заголовок при звонке request.is_ajax(), запрос никогда не был идентифицирован как запрос ajax, и, следовательно, заголовки без кеширования не были установлены.

def is_ajax(self):
        return self.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'

Проблема решена установкой underscores_in_headers к on в конфиге nginx. это Почта указал мне в правильном направлении.