La porción comprimida con gzip contenido de django

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

NOTAS:

  • Me doy cuenta de que esto no es una práctica recomendada y estoy más probable que va a utilizar la llamada mod_gzip. Esto es sólo un ejercicio de aprendizaje para entender lo que está pasando.
  • Sé acerca de la Django gzip middleware-que 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

Que me estoy perdiendo algo aquí? Es posible que el contenido de longitud que está mal? Hay encabezados adicionales que me falta?

Gracias.

  • BTW… si estás usando Apache 2.x, echa un vistazo a mod_deflate… es un poco más avanzada que mod_zip.
InformationsquelleAutor pjbeardsley | 2009-06-05

6 Kommentare

  1. 24

    zlib es un poco demasiado bajo nivel para este propósito. He aquí cómo el GZip middleware sí 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, pero en su propio zlib produce contenido codificados incorrectamente para un navegador de ver ‘gzip’, como la codificación del contenido. Espero que ayude!

  2. 88

    También puede simplemente utilizar Django es GZip Middleware:

    Habilitando el middleware en settings.py agregando:

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

    O hacerlo antes de devolver una respuesta concreta. En su views.py dec 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

    NOTA: Usted debe ser ciertos que no están sujetos a ataques de canal lateral antes de usar GZip middleware.

    Advertencia

    Los investigadores de seguridad reveló recientemente que cuando la compresión
    técnicas (incluyendo GZipMiddleware) son utilizados en un sitio web, el sitio
    puede verse expuestos a un número de posibles ataques. Antes de usar
    GZipMiddleware en su sitio, usted debe considerar muy cuidadosamente
    si usted está sujeto a estos ataques. Si tienes alguna duda acerca de
    si usted está afectado, debe evitar el uso de GZipMiddleware.
    Para
    más detalles, vea el INCUMPLIMIENTO de papel (PDF) y breachattack.com.

    También:

    Cambiado en Django 1.10: En versiones anteriores, Django la protección CSRF
    el mecanismo era vulnerable a la VIOLACIÓN de los ataques cuando la compresión se utiliza.
    Este no es el caso, pero usted debe tener cuidado de no
    comprometer su propia secretos de esta manera.

    • Tenga en cuenta corriente de las advertencias de seguridad relativas a la gzip middleware: docs.djangoproject.com/en/1.9/ref/middleware/…
    • Cuando traté de esto, tengo No module named middlware.gzip. La adición de @gzip_pageen la parte superior de mi punto de vista métodos trabajado aunque. Alguna idea de cuál es el problema? Estoy en Django 1.9
    • usted debe utilizar cadenas para especificar un middleware de la clase, no la clase/módulo de sí mismo. Así que en lugar de MIDDLEWARE_CLASSES = [django.middleware.gzip.GZipMiddleware,] que debe hacer: MIDDLEWARE_CLASSES = ["django.middleware.gzip.GZipMiddleware",]
    • Como de 1.10, Django incluye métodos para mitigar el INCUMPLIMIENTO de ataque, resolver el problema de seguridad Tobias anteriormente señalados. docs.djangoproject.com/en/1.11/ref/middleware
    • Debido a cuestiones de seguridad y como se comentó anteriormente, me gustaría ir con el decorador de enfoque.
  3. 24

    Si estás 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

    • Por cierto, esto es válido para Django 1.11.x y para una Django problema, una Django solución debe ser aceptada respuesta en mi humilde opinión.
  4. 1

    Si usted necesita para una sola página y usted está utilizando la clase de puntos de vista, el uso de este:

    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)

    A continuación, en la vista real:

    class MyView(GZipMixin, View):
        def get(self, request, *args, **kwargs):
             #return your response
  5. 0

    Si usted comprimir sus datos con zlib, usted tiene que fijar Content-Encoding a deflate, no 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

    De Codificación De Contenido

    (…)

    desinflar

    El uso de la zlib estructura (definido en RFC 1950) con el algoritmo de compresión deflate (definido en RFC 1951).

  6. -1

    Por el bien de los demás encontrando de esta cuestión y que están usando nginx, esta TAN trabajado para mí:

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

    Básicamente de inflexión gzip en el /etc/nginx/nginx.conf archivo hicieron todos los de la compresión de manejo para mí. En el lado del cliente, la mayoría de los navegadores modernos manejar automáticamente extraer (descomprimir) los datos cuando recibe – dulce!

    Aquí es el nginx.conf archivo de configuración:

        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;
        }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea