当我加载一个html页面时,我有一个5个字符串,大约相隔一秒.
<br>1</br>
...... 1 second ......
<br>2</br>
...... 1 second ......
<br>3</br>
...... 1 second ......
<br>4</br>
...... 1 second ......
<br>5</br>
...... 1 second ......
--- end request ---
Run Code Online (Sandbox Code Playgroud)
Chromium和Firefox都会加载并显示第一个br,然后显示下一个br.(但Firefox需要内容编码).但在请求结束之前,Safari拒绝显示任何标记.
铬似乎只是这样做.
Firefox首先需要确定内容编码https://bugzilla.mozilla.org/show_bug.cgi?id=647203
但Safari似乎只是拒绝.是否需要不同的响应代码或标头?我尝试将内容类型明确设置为text/html.没工作.
我已经在Wireshark中确认字符串是分开发送的,即它们不会被缓存并立即发送.
我也确认如果我通过localhost或我使用我的公共IP地址会发生这种情况.
我已经尝试了内容长度并保持活着,前者只是自动关闭请求,后者似乎没有效果.
Wireshark的标题和回应
Firefox(工作)
GET /pe HTTP/1.1
Host: 127.0.01:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Cache-Control: max-age=0
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Tue, 10 Nov 2015 17:10:20 GMT
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Server: TwistedWeb/13.2.0
1f
<html>
<title>PE</title>
<body>
2e
<br> This is the 1th time I've written. </br>
2e
<br> This is the 2th time I've written. </br>
2e
<br> This is the 3th time I've written. </br>
2e
<br> This is the 4th time I've written. </br>
2e
<br> This is the 5th time I've written. </br>
8
</body>
8
</html>
0
Run Code Online (Sandbox Code Playgroud)
Safari(不工作)
GET /pe HTTP/1.1
Host: 127.0.0.01:8080
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 Safari/601.1.56
Accept-Language: en-us
DNT: 1
Connection: keep-alive
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Tue, 10 Nov 2015 17:12:55 GMT
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Server: TwistedWeb/13.2.0
1f
<html>
<title>PE</title>
<body>
2e
<br> This is the 1th time I've written. </br>
2e
<br> This is the 2th time I've written. </br>
2e
<br> This is the 3th time I've written. </br>
2e
<br> This is the 4th time I've written. </br>
2e
<br> This is the 5th time I've written. </br>
8
</body>
8
</html>
0
Run Code Online (Sandbox Code Playgroud)
演示
import twisted
from twisted.python import log
import sys
log.startLogging(sys.stdout)
from twisted.web.server import Site, NOT_DONE_YET
from twisted.web.resource import Resource
from twisted.internet import reactor
class PersistantExample(Resource):
'''Gives an example of a persistant request'''
# does not exist on Safari until stopping browser / ending connection
isLeaf = True
def render_GET(self, request):
log.msg("Ooooh a render request")
# schedule the reoccuring thing (this could be something else like a deferred result)
reactor.callLater(1.1, self.keeps_going, request, 0) # 1.1 seconds just to show it can take floats
# firefox require the char set see https://bugzilla.mozilla.org/show_bug.cgi?id=647203
request.responseHeaders.addRawHeader("Content-Type",
"text/html; charset=utf-8") # set the MIME header (charset needed for firefox)
# this will cause the connection to keep only open for x length
# (only helpful if the length is known, also does NOT make it render right away)
# request.responseHeaders.addRawHeader("Content-Length", "150")
request.write("<html>\n<title>PE</title>\n<body>")
return NOT_DONE_YET
def keeps_going(self, request, i):
log.msg("I'm going again....")
i = i + 1
request.write("\n<br> This is the %sth time I've written. <br>" % i) ## probably not best to use <br> tag
if i < 5:
reactor.callLater(1.1, self.keeps_going, request, i) # 1.1 seconds just to show it can take floats
if i >= 5 and not request.finished:
log.msg("Done")
request.write("\n</body>")
request.write("\n</html>")
# safari will only render when finished
request.finish()
class Root(Resource):
isLeaf = False
def render_GET(self, request):
return "<html><body>Demo is <a href=\"pe\">here</a></body></html>"
class Site(Site):
pass
root = Root()
pe = PersistantExample()
site = Site(root)
root.putChild("", root)
root.putChild("index", root)
root.putChild("pe", pe)
# listen
if __name__ == "__main__":
reactor.listenTCP(8080, site)
reactor.run()
Run Code Online (Sandbox Code Playgroud)
为了让 Safari 能够渲染 html,在开始渲染接收到的 HTML 之前,至少必须写入 1024 个字节。
您可以在下面看到一个显示工作版本和非工作版本的演示。Firefox 中也会发生类似的情况(因为它需要 1024 字节来确定编码),但您可以在 Firefox 中设置编码以绕过它。不确定 Safari 中是否有办法做到这一点。
+---------------------------------------------------+
| What you send | How much you need |
+---------------------------------------------------+
| Nothing | 1024 bytes |
+---------------------------------------------------+
| Meta Charset | 512 bytes |
+---------------------------------------------------+
| Header Charset | 512 bytes (not including header) |
+---------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
import twisted
from twisted.python import log
import sys
log.startLogging(sys.stdout)
from twisted.web.server import Site, NOT_DONE_YET
from twisted.web.resource import Resource
from twisted.internet import reactor
import time
# max 133
# 133 * 8 = 1064
html_string_working = "<p>" # 3 bytes
html_string_working += "I'm the version that works! I show up right away!" # 49 bytes
html_string_working += "<!---" # 5 bytes
html_string_working += " " * (1024 - (3+49+5+3+4)) # filler
html_string_working += "-->" # 3 bytes
html_string_working += "</p>" # 4 bytes
print len(html_string_working)
html_string_non_working = "<p>" # 3 bytes
html_string_non_working += "I'm the version that does not work! I don't show up right away!" # 63 bytes
html_string_non_working += "</p>" # 4 bytes
html_string_non_working += "<!---" # 5 bytes
html_string_non_working += " " * (1023 - (3+63+5+3+4)) # filler but one byte short (notice 1023 instead of 1024)
html_string_non_working += "-->" # 3 bytes
print len(html_string_non_working)
# charset maybe? Firefox won't start parsing until 1024
# unless it has charset specified see https://bugzilla.mozilla.org/show_bug.cgi?id=647203
# "Your script does not appear to declare the character encoding. When the character
# encoding is not declared, Gecko won't start parsing until it has received 1024
# bytes of HTTP payload."
# charset works but requires 512 bytes
html_string_charset = "<meta charset=utf-8>" # 20 bytes
html_string_charset += "<p>" # 3 bytes
html_string_charset += "I'm the meta charset version. I may work!" # 41 bytes
html_string_charset += "</p>" # 4 bytes
html_string_charset += "<!---" # 5 bytes
html_string_charset += " " * (512 - (20+3+41+5+3+4)) # filler but one byte short (512 bytes; 511 doesn't work)
html_string_charset += "-->" # 3 bytes
# what about in header form
# charset works but requires 512 bytes not including the headers (so same as meta version)
html_string_charset_headers = "<p>" # 3 bytes
html_string_charset_headers += "I'm the header charset version. I may work!" # 43 bytes
html_string_charset_headers += "</p>" # 4 bytes
html_string_charset_headers += "<!---" # 5 bytes
html_string_charset_headers += " " * (512 - (3+43+5+3+4)) # filler but one byte short (512 bytes; 511 doesn't work)
html_string_charset_headers += "-->" # 3 bytes
print len(html_string_charset_headers)
later = "<p> I'm written later. Now it suddenly will work because bytes >= 1024." # 71 bytes
class PersistantExample(Resource):
'''Gives an example of a persistant request'''
# does not exist on Safari until stopping browser / ending connection
isLeaf = True
def render_GET(self, request):
log.msg("Ooooh a render request")
# schedule the reoccuring thing (this could be something else like a deferred result)
# firefox require the char set see https://bugzilla.mozilla.org/show_bug.cgi?id=647203
# render working version or not
try:
w = int(request.args["w"][0])
except:
w = 1
if w == 1:
request.write(html_string_working)
elif w == 2:
request.write(html_string_non_working)
elif w == 3:
request.write(html_string_charset)
elif w == 4:
# 12 + 24 = 36 bytes but doesn't count towards 512 total
request.responseHeaders.addRawHeader("Content-Type", "text/html; charset=utf-8")
request.write(html_string_charset_headers)
reactor.callLater(2, self.run_later, request)
return NOT_DONE_YET
def run_later(self, request):
request.write(later)
request.finish()
class Root(Resource):
isLeaf = False
def render_GET(self, request):
return """<html><body>
<p><a href="pe?w=1">Working version here</a></p>
<p><a href="pe?w=2">Non working version here</a></p>
<p><a href="pe?w=3">Meta charset version here</a></p>
<p><a href="pe?w=4">Header charset version here</a></p>
</body></html>"""
class Site(Site):
pass
root = Root()
pe = PersistantExample()
site = Site(root)
root.putChild("", root)
root.putChild("index", root)
root.putChild("pe", pe)
# listen
if __name__ == "__main__":
print "Running"
reactor.listenTCP(8080, site)
reactor.run()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |