Django Response 总是用 text/html 分块无法设置 Content-Length [英] Django Response always Chunked with text/html cannot set Content-Length

查看:23
本文介绍了Django Response 总是用 text/html 分块无法设置 Content-Length的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 Django 应用程序的 views.py 中,我在尝试设置以下 HTTP 标头字段后返回一个 HttpResponse 对象:

In my Django Application's views.py , I return an HttpResponse object after attempting to set the following HTTP Header fields:

# Create a Response Object with the content to return 
response = HttpResponse("%s"%(output_display),mimetype='text/html')
response['Cache-Control'] = 'must-revalidate, max-age=20'
response['Vary'] = 'Accept-Encoding'
response['Transfer-Encoding'] = 'gzip'
#response['Content-Encoding'] = 'gzip'
response['Connection'] = 'close'
#response['Content-Type'] = 'text/html'
response['Content-Length'] = '%s'%(len(output_display))
return response

然后我使用带有 FireFox 的 Live HTTP Headers 插件捕获输出,它看起来像:

I then capture the output using the Live HTTP Headers plugin with FireFox, and it looks like:

HTTP/1.1 200 OK
Date: Sun, 10 Mar 2013 14:55:09 GMT
Server: Apache/2.2.22 (Ubuntu)
Transfer-Encoding: gzip, chunked   <---------- Why 'chunked'?
Vary: Accept-Encoding
Connection: close
Cache-Control: must-revalidate, max-age=20
Content-Encoding: gzip
Content-Type: text/html <---------------------- No Content-Length even though I set it?
X-Pad: avoid browser bug

我正在尝试使用 Apache2 的 mem_cache 进行缓存,因此我需要设置内容长度并且不能为传输编码设置分块".

I am trying to cache using Apache2's mem_cache, so I need the Content-Length to be set and cannot have 'chunked' for Transfer-Encoding.

我的 Apache2 mem_cache.conf 看起来像(大量仅用于测试):

My Apache2 mem_cache.conf looks like ( large numbers just for testing ):

<IfModule mod_mem_cache.c>
        CacheEnable mem /
        MCacheSize 10000
        MCacheMaxObjectCount 10000000
        MCacheMinObjectSize 1
        MCacheMaxObjectSize 10000000
        MCacheMaxStreamingBuffer 10000000
</IfModule>

但即使我在响应代码中明确设置了 Content-Length 和 Transfer-Encoding,chunked"也会自动插入,因此我的 Content-Length 没有得到遵守.为什么是这样?如何解决此问题以获得所需的响应?谢谢-

But even though I explicitly set the Content-Length and Transfer-Encoding in my response code, 'chunked' is inserted automatically and therefore my Content-Length is not honored. Why is this? How can I fix this to get the desired response? Thanks -

推荐答案

我最近在使用 mod_wsgi 应用程序时遇到了类似的问题;我试图更新一个使用其内置磁盘缓存的 apache 配置,改为使用 socache/memcache.

I came across a similar issue recently with a mod_wsgi application; I was trying to update an apache configuration that was using its built-in disk cache, to use socache/memcache instead.

磁盘缓存工作正常,但切换到 memcache 或 shmcb 不起作用.如果我发出对我想要缓存的资源的请求,它不会将它存储在缓存中(CacheDetailHeader 对此很有帮助).在调试时检查日志,我发现了消息:

The disk cache was working, but switching to memcache or shmcb didn't work. If I issued a request for a resource I wanted cached, it wouldn't store it in the cache (CacheDetailHeader is helpful for this). Checking the logs at debug, I found the message:

[Wed Dec 05 18:52:16.571002 2018] [cache_socache:debug] \
[pid 884:tid 140422596777728] mod_cache_socache.c(389): \
[client 127.0.0.1:56576] AH02346: URL 'http://127.0.1.1:80/cacheme/c?' \
had no explicit size, ignoring, referer: http://127.0.0.1/

似乎socache 不喜欢没有明确大小的对象.我尝试将那些 mod_memcache 设置的较新的 socache 等效项设置为足够大的值:CacheSocacheMaxSizeCacheSocacheReadSize.

It seems that socache doesn't like objects that don't have explicit sizes. I tried setting the newer, socache equivalents of those mod_memcache settings to sufficiently large values: CacheSocacheMaxSize and CacheSocacheReadSize.

我知道 Content-Length 标头已被设置并传递到某个地方;当我故意错误计算它时,它出现在 mod_wsgi 日志中.

I know that the Content-Length header was being set and made it through to somewhere; it showed up in the mod_wsgi logs when I deliberately miscalculated it.

我发现的一些事情:

  1. 不要自己设置 Transfer-Encoding 标头,因为这是 WSGI 规范禁止的:

  1. Don't set Transfer-Encoding header yourself, as this is forbidden by the WSGI specification:

谁设置了传输编码:分块标头?

  • 即使您自己设置 Content-Length 标头,它也会被 apache 压缩.这会改变长度;当 Apache 不知道长度是多少时,它会切换到分块并删除 Content-Length 标头.

  • Even though you're setting the Content-Length header yourself, it's also being gzipped by apache. This changes the length; when Apache doesn't know what the length will be, it switches to chunked and removes the Content-Length header.

    我发现:

    • 内容类型:text/html

    Content-Length 设置为我的 utf-8 编码大小

    Content-Length set to my utf-8 encoding size

    在 python/mod_wsgi 应用程序中设置,并且:

    set in the python/mod_wsgi application, and:

    • SetEnv no-gzip 1

    在 apache 配置中设置,该对象将其放入 shmcb 缓存中.

    set in the apache configuration, that the object made it into a shmcb cache.

    看起来当 apache gzip 一个对象时,它会将标头更改为不被 socache 接受.

    It looks like when apache gzips an object, it changes the headers to that it isn't accepted by socache.

    我四处寻找使它们兼容的方法,但在这个问题上找不到太多.在 mod_cache 文档中有一些提到重新排序缓存/放气过滤器:

    I looked around for ways to make them compatible, but couldn't find too much on this issue. There is some mention of reordering the cache/deflate filters in the mod_cache documentation:

    https://httpd.apache.org/docs/2.4/mod/mod_cache.html#finecontrol

    如果我放入一个指令来重新排序缓存/放气过滤器,这会起作用:

    This worked if I put in a directive to reorder the cache/deflate filters:

    # within a directory
    SetOutputFilter CACHE;DEFLATE
    

    奇怪的是,在缓存未命中时,服务器返回 gzipped 内容,但在缓存命中时,服务器返回未编码的文本/html.这看起来很奇怪,但我对 FilterChain 指令的理解不够好,无法尝试.

    Curiously, on a cache miss, the server returned gzipped content, but on a cache hit, the server returned unencoded text/html. This looks odd, but I haven't understood the FilterChain directives well enough to try those out.

    我还在一个与 php/content-length 相关的问题中发现了这一点:

    I also found some mention of this in a related issue with php/content-length:

    https://serverfault.com/questions/183843/content-length-not-sent-when-gzip-compression-enabled-in-apache

    那里的答案发现,如果他们将 DeflateBufferSize 设置为足够大的值,则将设置 content-length.

    The answer there found that if they set the DeflateBufferSize to a large-enough value, then content-length would be set.

    我无法让它工作.

    所以看起来人们在选择缓存还是 gzip 之间陷入了困境.

    So it looks like one is stuck between choosing cached or gzipped.

    这篇关于Django Response 总是用 text/html 分块无法设置 Content-Length的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆