在Python 3中从CGI输出二进制数据 [英] Output binary data from CGI in Python 3

查看:219
本文介绍了在Python 3中从CGI输出二进制数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题与这个问题有关.从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.

有想法吗?

已添加:将来的注意事项:

这也意味着print对于CGI不再有用.

This also means print is no good for CGI any more.

推荐答案

使用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输出二进制数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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