提供来自django的Gzip内容

提供来自django的Gzip内容,django,http,gzip,Django,Http,Gzip,我试图在Django中提供文本/html页面的gzip版本,但Firefox告诉我有一个内容编码错误 注: 我意识到这不是一个最佳实践,我很可能会使用mod_gzip。这只是一个了解发生了什么的学习练习 我知道Django gzip中间件——它在二进制文件方面有问题 这是我的密码: rendered_page = zlib.compress(template.render(context).encode('utf-8')) response = HttpResponse(rendered

我试图在Django中提供文本/html页面的gzip版本,但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
我是不是遗漏了什么?内容长度是否可能有误?是否有我丢失的其他标题


谢谢。

zlib
对于这个目的来说有点太低级了。以下是GZip中间件本身的工作方式(请参阅中的压缩字符串):

GZip使用zlib,但zlib本身产生的内容编码不正确,浏览器将“GZip”视为内容编码。希望有帮助

您也可以简单地使用:

通过在settings.py中启用中间件或添加:

MIDDLEWARE_CLASSES = (
    django.middleware.gzip.GZipMiddleware,
    ...
)
或者在返回特定响应之前执行此操作。在your 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)在网站上使用 可能会受到一些可能的攻击。使用前 GZIP中间件在你的站点上,你应该仔细考虑 你是否受到这些攻击如果您对 无论您是否受到影响,都应避免使用GZipMiddleware。 更多详细信息,请参阅违约文件(PDF)和breakattack.com

此外:

在Django 1.10中更改:在旧版本中,Django的CSRF保护 当使用压缩时,该机制容易受到破坏攻击。 现在已经不是这样了,但你还是要注意不要这样做 以这种方式泄露你自己的秘密


如果要对单个页面进行gzip压缩,而不是对所有页面进行gzip压缩,则可以使用gzip\u页面decorator而不是gzip iddleware

from django.views.decorators.gzip import gzip_page

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

此处参考:

为了让其他人发现这个问题以及使用nginx的人,这对我来说非常有用:

基本上,在/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;
    }

如果单个页面需要它,并且使用基于类的视图,请使用以下选项:

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

如果使用
zlib
压缩数据,则必须将
内容编码
设置为
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
(……)

放气

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


顺便提一下如果您使用的是Apache2.x,请浏览mod_deflate。。。它比mod_zip更高级。请注意当前关于gzip中间件的安全警告:当我尝试此操作时,我没有得到名为middlware.gzip的模块。在我的视图上添加
@gzip\u页面
,方法仍然有效。知道问题出在哪里吗?我在Django 1。9@hd1您应该使用字符串来指定中间件类,而不是类/模块本身。因此,从1.10开始,django不应该使用
MIDDLEWARE\u CLASSES=[django.MIDDLEWARE.gzip.gzip iddleware],而应该使用
MIDDLEWARE\u CLASSES=[“django.MIDDLEWARE.gzip.GZipMiddleware”]
来解决上述安全问题。由于安全问题,如上所述,我选择decorator方法。顺便说一句,这对Django 1.11.x仍然有效,对于Django问题,Django解决方案应该是IMHO接受的答案。
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