Обслуживание содержимого gzipped из django
Я пытаюсь выполнить gzipped версию страницы text/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
Я что-то упустил? Возможно ли, что длина контента неверна? Есть ли дополнительные заголовки, которые мне не хватает?
Спасибо.
Ответы
Ответ 1
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" в качестве кодировки содержимого. Надеюсь, что это поможет!
Ответ 2
Вы также можете просто использовать django gzip middleware:
Либо включив промежуточное программное обеспечение в 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
Ответ 3
Если вы используете gzipping на одной странице, а не на всех страницах, вы можете использовать декоратор 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
Ответ 4
Для других, которые находят этот вопрос и кто использует nginx, этот SO работал у меня:
fooobar.com/info/166921/...
В основном, 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;
}