Обслуживание сжатого контента от Django - PullRequest
36 голосов
/ 05 июня 2009

Я пытаюсь открыть gzip-версию текстовой / html-страницы в Django, но Firefox сообщает мне, что есть ошибка кодирования контента.

ПРИМЕЧАНИЯ:

  • Я понимаю, что это не лучшая практика, и я, скорее всего, буду использовать mod_gzip. Это всего лишь учебное упражнение, чтобы понять, что происходит.
  • Я знаю о промежуточном программном обеспечении Django gzip - у него проблемы с двоичными файлами.

Вот мой код:

rendered_page =  zlib.compress(template.render(context).encode('utf-8'))

response = HttpResponse(rendered_page)
response['Content-Encoding'] = 'gzip'
response['Content-Length'] = len(rendered_page)
return response

Я что-то здесь упускаю? Возможно ли, что длина контента неверна? Есть ли дополнительные заголовки, которые мне не хватает?

Спасибо.

Ответы [ 6 ]

85 голосов
/ 08 декабря 2009

Вы также можете просто использовать Промежуточное ПО GZip от Django :

Либо включив промежуточное ПО в settings.py, добавив:

MIDDLEWARE_CLASSES = (
    django.middleware.gzip.GZipMiddleware,
    ...
)

Или сделайте это, прежде чем вернуть конкретный ответ. В вашем views.py, dec будет обработчиком для определенного URL

from django.middleware.gzip import GZipMiddleware

gzip_middleware = GZipMiddleware()

 def dec(request, *args, **kwargs):
        response = func(request, *args, **kwargs)
        return gzip_middleware.process_response(request, response)
        return dec

ПРИМЕЧАНИЕ. Вы должны быть уверены , что вы не должны подвергаться атакам по побочным каналам перед использованием промежуточного программного обеспечения GZip.

Внимание

Исследователи безопасности недавно обнаружили, что при сжатии методы (в том числе GZipMiddleware) используются на сайте, сайте может подвергнуться ряду возможных атак. Перед использованием GZipMiddleware на вашем сайте, вы должны очень внимательно рассмотреть подвержены ли вы этим атакам. Если вы сомневаетесь в независимо от того, затронуты ли вы, вам следует избегать использования GZipMiddleware. Для подробнее см. документ BREACH (PDF) и breachattack.com.

Также:

Изменено в Django 1.10: в старых версиях защита CSRF от Django Механизм был уязвим для атак BREACH при использовании сжатия. Это больше не так, но вы все равно должны позаботиться о том, чтобы раскрыть свои секреты таким образом.

22 голосов
/ 05 июня 2009

zlib слишком низкий уровень для этой цели. Вот как это делает само промежуточное ПО GZip (см. Compress_string в django.utils.text.py ):

import cStringIO, gzip
zbuf = cStringIO.StringIO()
zfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=zbuf)
zfile.write(template.render(context).encode('utf-8'))
zfile.close()

compressed_content = zbuf.getvalue()
response = HttpResponse(compressed_content)
response['Content-Encoding'] = 'gzip'
response['Content-Length'] = str(len(compressed_content))
return response

GZip использует zlib, но сам zlib создает контент, который неправильно закодирован для браузера, который видит кодировку «gzip». Надеюсь, это поможет!

21 голосов
/ 12 февраля 2013

Если вы распаковываете одну страницу, но не для всех страниц, вы можете использовать декоратор gzip_page вместо GzipMiddleware.

from django.views.decorators.gzip import gzip_page

@gzip_page
def viewFunc(request):
  return HttpResponse("hello"*100)

Ссылка здесь: https://docs.djangoproject.com/en/1.4/topics/http/decorators/#module-django.views.decorators.gzip

1 голос
/ 05 апреля 2018

Если вам это нужно для одной страницы, и вы используете представления на основе классов, используйте это:

gzip_middleware = GZipMiddleware()

class GZipMixin(object):

    def dispatch(self, request, *args, **kwargs):
        response = super(GZipMixin, self).dispatch(request, *args, **kwargs)
        return gzip_middleware.process_response(request, response)

Тогда в вашем текущем виде:

class MyView(GZipMixin, View):
    def get(self, request, *args, **kwargs):
         #return your response
0 голосов
/ 15 февраля 2019

Если вы сжимаете данные с помощью zlib, вы должны установить Content-Encoding на deflate, а не gzip.

rendered_page =  zlib.compress(template.render(context).encode('utf-8'))

response = HttpResponse(rendered_page)
response['Content-Encoding'] = 'deflate'
response['Content-Length'] = len(rendered_page)
return response

Content-Encoding

(...)

выкачать

Использование структуры zlib (определенной в RFC 1950) с алгоритмом сжатия с раздувом (определенной в RFC 1951).

0 голосов
/ 24 января 2017

Ради других, которые находят этот вопрос и используют nginx, это ТАК работает для меня:

https://stackoverflow.com/a/41820704/4533488

По сути, включение gzip в файле /etc/nginx/nginx.conf сделало всю обработку сжатия за меня. На стороне клиента большинство современных браузеров автоматически обрабатывают извлечение (распаковку) данных при их получении - сладко!

Вот настройки файла nginx.conf:

    http {

        #... other settings ...#

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...