提供来自django的gzip压缩内容

b91juud3  于 2022-11-18  发布在  Go
关注(0)|答案(6)|浏览(178)

我 试图 在 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

中 的 每 一 个
我 是否 遗漏 了 什么 ? 内容 长度 是否 有误 ? 是否 遗漏 了 其他 标题 ?

  • 谢谢 - 谢谢
yhived7q

yhived7q1#

你也可以简单地使用Django的GZip中间件:
通过在www.example.com中添加以下内容来启用中间件settings.py:

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

在www.example.com中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。**有关详细信息,请参阅BREACH白皮书(PDF)和breachattack.com。
还有:
Django 1.10中的更改:在旧版本中,Django的CSRF保护机制在使用压缩时容易受到BREACH攻击。现在情况已经不是这样了,但你仍然要注意不要以这种方式泄露你自己的秘密。

8wtpewkr

8wtpewkr2#

如果您要对单个页面进行gzip压缩,而不是对所有页面进行gzip压缩,则可以使用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

z4iuyo4d

z4iuyo4d3#

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'作为内容编码。希望这能有所帮助!

5t7ly7z5

5t7ly7z54#

为了其他人找到这个问题,谁正在使用nginx,这对我来说是如此的工作:
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;
    }
bwleehnv

bwleehnv5#

如果您需要在单个页面中使用它,并且您正在使用基于类的视图,请使用以下命令:

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
gab6jxml

gab6jxml6#

如果使用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中定义)。

相关问题