起初,我认为http stream实际上是实现http块的。
所以我做了一个测试来学习。
这是一个姜戈视图
def test_stream(request):
return StreamingHttpResponse(func)
函数返回可迭代 这是使用 curl 访问视图的输出
curl -vv -raw http://172.25.44.238:8004/api/v1/admin/restart_all_agent?cluster_id='dd5aef9cbe7311e99585f000ac192cee' -i
Warning: Invalid character is found in given range. A specified range MUST
Warning: have only digits in 'start'-'stop'. The server's response to this
Warning: request is uncertain.
* About to connect() to 172.25.44.238 port 8004 (#0)
* Trying 172.25.44.238...
* Connected to 172.25.44.238 (172.25.44.238) port 8004 (#0)
> GET /api/v1/admin/restart_all_agent?cluster_id=dd5aef9cbe7311e99585f000ac192cee HTTP/1.1
> Range: bytes=aw
> User-Agent: curl/7.29.0
> Host: 172.25.44.238:8004
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
Content-Type: text/html; charset=utf-8
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
* no chunk, no close, no size. Assume close to signal end
<
some http response body.
* Closing connection 0
从输出中,您可以看到没有分块标头。似乎 Http 流与块无关。
所以这里有一个问题
http- 流是由 http chunk 实现的吗?
- 如何在 django 中返回分块响应?
不,流式传输与分块没有任何关系。您可以有一个带或不带另一个。
流式处理响应的优点是不需要一次将整个响应作为字符串加载到内存中。
这篇博客文章在解释用例方面做得很好:https://andrewbrookins.com/django/how-does-djangos-streaminghttpresponse-work-exactly/
它还涵盖了返回分块响应所需的内容,我将总结一下:
- 使用类
StreamingHttpResponse
但提供一个可迭代的(列表,生成器...(作为第一个参数而不是字符串。 -
不要设置
Content-Length
标头。 - 您需要使用一个网络服务器来为您分块响应。Django 本身不会这样做,也不会发生在
manage.py runserver
身上(但uvicorn
和gunicorn
这样做,例如(
from django.urls import path
from django.http import StreamingHttpResponse
def generator():
for i in range(0, 100):
yield str(i) * 1024 * 1024
def chunked_view(request):
return StreamingHttpResponse(generator(), content_type='text/plain')
urlpatterns = [path('chunked', chunked_view)]
使用uvicorn myapp.asgi:application
运行 Django 应用程序。
curl -v http://127.0.0.1:8000/chunked > /dev/null
在响应标头中显示transfer-encoding: chunked
。