如何在完全下载之前显示html页面

时间:2017-05-09 23:59:16

标签: python http

我在保持活动会话期间在相同的响应中发送html内容(它有一点延迟)之后发送一些数据,并希望浏览器在下载整个响应之前显示html。

例如,我有一个文本'hello, '和一个用延迟计算'world'的函数(让它为1秒)。所以我希望浏览器立即显示'hello, ',并'world'显示延迟。是否可以在一个请求中(因此,没有ajax)

以下是我所做的示例python代码(突出显示:https://pastebin.com/muUJyR36):

import socket
from time import sleep

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()

def give_me_a_world():
    sleep(1)
    return b'world'

while True:
    data = conn.recv(1024)
    response = b'HTTP/1.1 200 OK\r\n'\
               b'Content-Length: 12\r\n'\
               b'Connection: keep-alive\r\n'\
               b'\r\n'\
               b'hello, '

    conn.send(response) # send first part
    conn.send(give_me_a_world()) # make a delay and send other part

conn.close()

2 个答案:

答案 0 :(得分:0)

首先,请阅读How the web works: HTTP and CGI explained以了解当前代码违反HTTP的原因和位置,因此不会也不应该有效。

现在,根据Is Content-Length or Transfer-Encoding is mandatory in a response when it has body,在修复违规后,您应该

  • 省略Content-Length标题并在发送所有数据后关闭套接字,或者
  • 预先计算要发送的整个数据的长度,并在Content-Length标题
  • 中指定

答案 1 :(得分:0)

您可以使用Transfer-Encoding: chunked并省略Content-Length

它适用于文本浏览器,如 curl 链接WWW浏览器。但是,现代图形浏览器在到达某种缓冲区边界之前并没有真正开始渲染。

import socket
from time import sleep

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()

def give_me_a_world():
    sleep(1)
    return b'5\r\n'\
           b'world\r\n'\
           b'0\r\n'\
           b'\r\n'

while True:
    data = conn.recv(1024)
    response = b'HTTP/1.1 200 OK\r\n'\
               b'Transfer-Encoding: chunked\r\n'\
               b'Connection: keep-alive\r\n'\
               b'\r\n'\
               b'7\r\n'\
               b'hello, \r\n'

    conn.send(response) # send first part
    conn.send(give_me_a_world()) # make a delay and send other part

conn.close()