der*_*mai 6 python binary zip cgi python-3.x
我正在使用 Python 和 CGI 编写一个小型网站,用户可以在其中上传 zip 文件和下载其他用户上传的文件。目前,我可以正确上传 zip 文件,但是在将文件正确发送给用户时遇到了一些麻烦。我的第一种方法是:
file = open('../../data/code/' + filename + '.zip','rb')
print("Content-type: application/octet-stream")
print("Content-Disposition: filename=%s.zip" %(filename))
print(file.read())
file.close()
但很快我意识到我必须将文件作为二进制发送,所以我尝试:
print("Content-type: application/octet-stream")
print("Content-Disposition: filename=%s.zip" %(filename))
print('Content-transfer-encoding: base64\r')
print( base64.b64encode(file.read()).decode(encoding='UTF-8') )
以及它的不同变体。它只是行不通;Apache 引发“来自脚本的格式错误的标头”错误,所以我想我应该以其他方式对文件进行编码。
您需要在标题后打印一个空行,并且您的 Content-disposition 标题缺少类型 ( attachment):
print("Content-type: application/octet-stream")
print("Content-Disposition: attachment; filename=%s.zip" %(filename))
print()
您可能还想使用一种更有效的方法来上传结果文件;用于shutil.copyfileobj()将数据复制到sys.stdout.buffer:
from shutil import copyfileobj
import sys
print("Content-type: application/octet-stream")
print("Content-Disposition: attachment; filename=%s.zip" %(filename))
print()
with open('../../data/code/' + filename + '.zip','rb') as zipfile:
    copyfileobj(zipfile, sys.stdout.buffer)
print()在任何情况下,您都不应该使用二进制数据;你得到的只是b'...'字节文字语法。该sys.stdout.buffer对象是底层的二进制 I/O 缓冲区,将二进制数据直接复制到该缓冲区。
小智 5
标头格式错误,因为出于某种原因,Python 在发送文件后发送它。
您需要做的是在标头之后立即刷新标准输出:
sys.stdout.flush()
然后把文件copy