问题描述
这个问题与这个问题有关.从Python 2中的CGI脚本打印原始二进制数据时,我没有任何问题,例如:
This question is related to this one. I was having no problems while printing raw binary data from a CGI script in Python 2, for example:
#!/usr/bin/env python2
import os
if __name__ == '__main__':
with open(os.path.abspath('test.png'), 'rb') as f:
print "Content-Type: image/png\n"
print f.read()
以下是相关的响应标头:
Here are the relevant response headers:
> GET /cgi-bin/plot_string2.py HTTP/1.1
> User-Agent: curl/7.32.0
> Host: 0.0.0.0:8888
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 Script output follows
< Server: SimpleHTTP/0.6 Python/3.3.2
< Date: Fri, 13 Sep 2013 16:21:25 GMT
< Content-Type: image/png
,按预期结果被解释为图像.但是,如果我尝试翻译成Python 3:
and the result is interpreted as an image, as expected. However, if I try to make a translation to Python 3:
#!/usr/bin/env python
import os
import sys
if __name__ == '__main__':
with open(os.path.abspath('test.png'), 'rb') as f:
print("Content-Type: image/png\n")
sys.stdout.buffer.write(f.read())
不返回任何内容,并且标题如下:
Nothing is returned, and here are the headers:
> GET /cgi-bin/plot_string3.py HTTP/1.1
> User-Agent: curl/7.32.0
> Host: 0.0.0.0:8888
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 Script output follows
< Server: SimpleHTTP/0.6 Python/3.3.2
< Date: Fri, 13 Sep 2013 16:22:13 GMT
< �PNG
<
我无法再执行print(f.read())
,因为那样会打印类似b'\x89PNG\r\n\x1a\n\x00...
的内容.我链接的问题提供了解决方案,但显然在这种环境下不起作用.
I cannot do print(f.read())
anymore because that will print something like b'\x89PNG\r\n\x1a\n\x00...
. The question I linked gives a solution, but apparently doesn't work in this environment.
有想法吗?
已添加:将来的注意事项:
推荐答案
使用sys.stdout.flush
强制将标题打印在正文之前:
Use sys.stdout.flush
to force the header printed before the body:
import os
import sys
if __name__ == '__main__':
with open(os.path.abspath('test.png'), 'rb') as f:
print("Content-Type: image/png\n")
sys.stdout.flush() # <---
sys.stdout.buffer.write(f.read())
或删除打印,并仅使用sys.stdout.buffer.write
:
Or remove print, and use sys.stdout.buffer.write
only:
import os
import sys
if __name__ == '__main__':
with open(os.path.abspath('test.png'), 'rb') as f:
sys.stdout.buffer.write(b"Content-Type: image/png\n\n") # <---
sys.stdout.buffer.write(f.read())
注意
f.read()
可能会导致问题.为防止这种情况,请使用 shutil.copyfileobj
:
f.read()
could cause a problem if the file is huge. To prevent that, use shutil.copyfileobj
:
import os
import shutil
import sys
if __name__ == '__main__':
with open(os.path.abspath('test.png'), 'rb') as f:
sys.stdout.buffer.write(b"Content-Type: image/png\n\n")
shutil.copyfileobj(f, sys.stdout.buffer)
这篇关于在Python 3中从CGI输出二进制数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!