我正在使用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标题缺少类型(附件):
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缓冲区,直接将二进制数据复制到该缓冲区.