2009-06-05 3 views
32

Ich versuche, eine gezippte Version einer Text/HTML-Seite in Django zu dienen, aber Firefox sagt mir, dass es einen Content-Encoding-Fehler ist.Serving gziped Inhalt von Django

HINWEISE:

  • Ich weiß, dies nicht eine bewährte Methode ist, und ich bin wahrscheinlich mod_gzip nicht benutzen will. Dies ist nur eine Lernübung, um zu verstehen, was vor sich geht.
  • Ich weiß über die Django Gzip Middleware - es hat Probleme mit Binärdateien.

Hier ist mein Code:

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 

Bin ich hier etwas fehlt? Ist es möglich, dass die Inhaltslänge falsch ist? Gibt es zusätzliche Header, die ich vermisse?

Danke.

+1

BTW ... wenn Sie Apache 2.x verwenden, haben einen Blick auf mod_deflate ... es ist ein bisschen weiter fortgeschritten als mod_zip. –

Antwort

22

zlib ist ein bisschen zu niedrig für diesen Zweck. Hier ist, wie die GZIP-Middleware selbst tut es (siehe compress_string in 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 verwendet, aber auf seine eigenen zlib produzieren Inhalte, die nicht richtig für einen Browser verschlüsselt sind ‚gzip‘ als Inhalt Codierung zu sehen. Ich hoffe, das hilft!

71

Sie könnten auch einfach Djangos gzip-Middleware verwenden:

Entweder durch die Middleware in settings.py ermöglicht durch Zusatz:

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

) 

Oder es tun, bevor Sie eine bestimmte Antwort zurück. In Ihrem views.py würde Dezember der Handler für eine bestimmte URL sein

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 Dies sollte die Antwort sein – shabeer90

+2

Bitte beachten Sie die aktuellen Sicherheitswarnungen bezüglich der gzip Middleware: https://docs.djangoproject.com/en/1.9/ref/middleware/#module-django.middleware.gzip –

+0

Als ich das versuchte Ich habe 'Kein Modul namens middlware.gzip'.Das Hinzufügen von '@ gzip_page'auf der Oberseite meiner Ansichtsmethoden funktionierte jedoch. Irgendeine Idee, was das Problem ist? Bin auf Django 1.9 – hd1

17

Wenn Sie einzelne Seite sind Gzipping, nicht für alle Seiten, Sie gzip_page Dekorateur statt GzipMiddleware verwenden können.

from django.views.decorators.gzip import gzip_page 

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

Referenz hier: https://docs.djangoproject.com/en/1.4/topics/http/decorators/#module-django.views.decorators.gzip

+0

Das funktionierte für mich ... – ATOzTOA

+0

Übrigens, das gilt immer noch für Django 1.11.x und für ein Django-Problem sollte eine Django-Lösung die akzeptierte Antwort sein. –

0

Für das Wohl des anderen, diese Frage zu finden, und wer verwendet nginx, das funktionierte so für mich:

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

Grundsätzlich auf gzip Drehen in der Die Datei /etc/nginx/nginx.conf hat die gesamte Komprimierungsbehandlung für mich erledigt. Auf der Client-Seite handhaben die meisten modernen Browser automatisch das Extrahieren (Dekomprimieren) der Daten beim Empfang - süß! Hier

ist die nginx.conf Dateieinstellungen:

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