2009-06-05 14 views
32

Estoy tratando de servir una versión comprimida de una página de texto/html en Django, pero Firefox me dice que hay un error de codificación de contenido.Sirviendo gzip contenido de django

NOTAS:

  • que se dan cuenta de que esto no es una buena práctica y estoy más probable va a utilizar mod_gzip. Esto es solo un ejercicio de aprendizaje para entender lo que está pasando.
  • Sé sobre el middleware Django gzip-- tiene problemas con los archivos binarios.

Aquí está mi código:

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 

Me estoy perdiendo algo aquí? ¿Es posible que la duración del contenido sea incorrecta? ¿Hay encabezados adicionales que me falta?

Gracias.

+1

Por cierto ... si estás usando Apache 2.x, tienen un vistazo a mod_deflate ... que es un poco más avanzado que mod_zip. –

Respuesta

22

zlib es un nivel demasiado bajo para este propósito. Así es como el propio middleware GZip lo hace (ver compress_string en 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 utiliza zlib, sino en su propia zlib produce contenido que está formulado correctamente codificado para un navegador de ver 'gzip' como la codificación de contenido. ¡Espero que ayude!

71

También podría simplemente utilizar gzip middleware de Django:

O al permitir que el middleware en settings.py añadiendo:

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

) 

O hacerlo antes de regresar una respuesta particular. En su views.py, diciembre sería el controlador para una determinada 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 
+6

+1 Esta debería ser la respuesta – shabeer90

+2

Tenga en cuenta las advertencias de seguridad actuales con respecto al middleware gzip: https://docs.djangoproject.com/en/1.9/ref/middleware/#module-django.middleware.gzip –

+0

Cuando probé esto , Obtuve 'Ningún módulo llamado middlware.gzip'.Sin embargo, agregué '@ gzip_page'on en la parte superior de mis métodos de vista. ¿Alguna idea de cuál es el problema? Estoy en Django 1.9 – hd1

17

Si está gzipping sola página, no para todas las páginas, puede utilizar gzip_page decorador en lugar de GzipMiddleware.

from django.views.decorators.gzip import gzip_page 

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

referencia aquí: https://docs.djangoproject.com/en/1.4/topics/http/decorators/#module-django.views.decorators.gzip

+0

Esto funcionó para mí ... – ATOzTOA

+0

Por cierto, esto sigue siendo válido para Django 1.11.x y para un problema de Django, una solución de Django debe ser la respuesta aceptada en mi humilde opinión. –

0

Por el bien de los demás búsqueda de esta cuestión y que están usando nginx, este SO trabajó para mí:

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

girando Básicamente gzip en el El archivo /etc/nginx/nginx.conf hizo todo el manejo de la compresión para mí. En el lado del cliente, la mayoría de los navegadores modernos manejan automáticamente la extracción (descompresión) de los datos cuando los recibe, ¡dulce!

Aquí está la configuración del archivo 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; 
    } 
Cuestiones relacionadas