2009-06-05 17 views
32

Sto provando a pubblicare una versione gzippata di una pagina di testo/html in Django, ma Firefox mi sta dicendo che c'è un errore di codifica del contenuto.Fornisce contenuto gzip da django

NOTE:

  • Mi rendo conto che non è una pratica migliore e sto molto probabilmente intenzione di utilizzare mod_gzip. Questo è solo un esercizio di apprendimento per capire cosa sta succedendo.
  • Conosco il middleware gzip Django: ha problemi con i file binari.

Ecco il mio codice:

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 

mi manca qualcosa qui? È possibile che la lunghezza del contenuto sia errata? Ci sono intestazioni aggiuntive che mi mancano?

Grazie.

+1

BTW ... se si sta utilizzando Apache 2.x, hanno una sbirciatina al mod_deflate ... è un po 'più avanzato rispetto mod_zip. –

risposta

22

zlib è un po 'troppo basso livello per questo scopo. Ecco come il middleware GZip in sé lo fa (vedi 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 utilizza zlib, ma di per sé zlib produce contenuti che è impropriamente codificato per un browser vedere 'gzip' come la codifica del contenuto. Spero possa aiutare!

71

Si potrebbe anche semplicemente usare gzip middleware di Django:

O attivando il middleware in settings.py aggiungendo:

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

) 

O farlo prima di tornare una particolare risposta. Nella tua views.py, dicembre sarebbe il gestore per un certo 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 Questa dovrebbe essere la risposta – shabeer90

+2

Si prega di notare gli attuali avvisi di sicurezza relativi al middleware gzip: https://docs.djangoproject.com/en/1.9/ref/middleware/#module-django.middleware.gzip –

+0

Quando ho provato questo , Ho ottenuto 'Nessun modulo chiamato middlware.gzip'.Tuttavia, l'aggiunta di '@ gzip_page' all'inizio dei miei metodi di visualizzazione ha funzionato. Qualche idea su quale sia il problema? Am on Django 1.9 – hd1

17

Se stai gzipping singola pagina, non per tutte le pagine, è possibile utilizzare gzip_page decoratore invece di GzipMiddleware.

from django.views.decorators.gzip import gzip_page 

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

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

+0

Questo ha funzionato per me ... – ATOzTOA

+0

A proposito, questo è ancora valido per Django 1.11.x e per un problema Django, una soluzione Django dovrebbe essere la risposta accettata IMHO. –

0

Per il bene degli altri trovare questa domanda e che stanno utilizzando nginx, questo SO ha funzionato per me:

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

Fondamentalmente girando gzip sul nel Il file /etc/nginx/nginx.conf ha fatto tutta la gestione della compressione per me. Sul lato client, i browser più moderni gestiscono automaticamente l'estrazione (decompressione) dei dati al momento della ricezione - dolce!

Ecco le impostazioni del file 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; 
    } 
Problemi correlati