我正在尝试在Django中提供一个gzip版本的text / html页面,但是Firefox告诉我内容编码错误。
注意:
这是我的代码:
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
我在这里遗漏了什么吗?内容长度是否有可能错误?我还缺少额外的标题吗?
感谢。
答案 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;
}