从django提供gzip压缩内容

时间:2009-06-05 19:07:54

标签: django http gzip

我正在尝试在Django中提供一个gzip版本的text / html页面,但是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

我在这里遗漏了什么吗?内容长度是否有可能错误?我还缺少额外的标题吗?

感谢。

6 个答案:

答案 0 :(得分:84)

您也可以使用Django's 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

注意:在使用GZip中间件之前,您应该某些不受旁道攻击。

  

警告

     安全研究人员最近透露,压缩时   技术(包括GZipMiddleware)用于网站,即网站   可能会受到一些可能的攻击。使用前   GZipMiddleware在您的网站上,您应该非常仔细地考虑   你是否受到这些攻击。 如果您有任何疑问   无论您是否受到影响,都应该避免使用GZipMiddleware。 For   更多详情,请参阅BREACH文件(PDF)和breachattack.com。

此外:

  

在Django 1.10中更改:在旧版本中,Django的CSRF保护   当使用压缩时,机制容易受到BREACH攻击。   现在不再是这种情况,但你仍然应该注意不要这样做   以这种方式妥协你自己的秘密。

答案 1 :(得分:22)

为此目的,

zlib有点太低级了。以下是GZip中间件本身的用法(参见django.utils.text.py中的compress_string):

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 :(得分:21)

如果您正在抓取单页而不是所有网页,则可以使用 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

答案 3 :(得分:1)

如果您需要单页并且使用基于类的视图,请使用:

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)

然后在您的实际视图中:

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

答案 4 :(得分:0)

如果使用zlib压缩数据,则必须将Content-Encoding设置为deflate,而不是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
  

Content-Encoding

     

(...)

     

放气

     

使用zlib结构(在RFC 1950中定义)和deflate压缩算法(在RFC 1951中定义)。

答案 5 :(得分:-1)

为了其他人找到这个问题以及谁在使用nginx,这个SO对我有用:

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

基本上在/etc/nginx/nginx.conf文件中打开gzip会对我进行所有压缩处理。在客户端,大多数现代浏览器在接收数据时自动处理提取(解压缩)数据 - 甜蜜!

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