如何在Python中通过cgi部署zip文件(或其他二进制文件)?

我正在使用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缓冲区,直接将二进制数据复制到该缓冲区.

上一篇:使用python的CGI表单提交按钮


下一篇:配置LNMP遇到的问题(页面空白,不能解析php等)以及fastcgi和php-fom的关系