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
ここで何か不足していますか?コンテンツの長さが間違っている可能性はありますか?不足している追加のヘッダーはありますか?
ありがとう。
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」を表示するブラウザーに対して不適切にエンコードされたコンテンツを生成します。お役に立てば幸いです。
DjangoのGZipミドルウェア を使用することもできます。
次のように追加して、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を含む)がWebサイトで使用されると、サイトがいくつかの可能な攻撃にさらされる可能性があることを明らかにしました。サイトでGZipMiddlewareを使用する前に、これらの攻撃を受けているかどうかを非常に慎重に検討する必要があります。 影響を受けるかどうか疑わしい場合は、GZipMiddlewareの使用を避けてください。詳細については、BREACHペーパー(PDF)を参照してください。とbreachattack.com。
また:
Django 1.10で変更:古いバージョンでは、DjangoのCSRF保護メカニズムは、圧縮が使用された場合のBREACH攻撃に対して脆弱でした。これはもはや当てはまりませんが、独自のセキュリティを侵害しないように注意する必要がありますこの方法で秘密。
すべてのページではなく単一のページをgzip圧縮する場合は、GzipMiddlewareの代わりにgzip_pageデコレータを使用できます。
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
単一のページで必要であり、クラスベースのビューを使用している場合は、これを使用します。
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
にContent-Encoding
を設定する必要があります。
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
(...)
deflate
Deflate圧縮アルゴリズム(RFC 1951で定義)でzlib構造(RFC 1950で定義)を使用します。
他の人がこの質問を見つけて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;
}