在Django中构建带有二进制图像数据的multipart/form-data时出现UnicodeDecodeError
--- 下面有一些额外的测试结果,请阅读 :) ---
我在用Python构建一个multipart/form-data格式的请求体时遇到了困难。简单来说,我是用一个字符串列表作为缓冲区,然后尝试把它们连接起来,这里是我的代码:
fp = open(filename, 'rb')
BOUNDARY = 's0m3r4ndomB0unD4ry'
body = []
body.append('--' + BOUNDARY)
body.append('Content-Disposition: form-data; name="image"; filename="%s"' % filename)
body.append('Content-Type: %s' % file_type)
body.append('')
body.append(fp.read())
body.append('--' + BOUNDARY + '--')
body.append('')
fp.close()
body = '\r\n'.join(body)
一开始看起来很简单,这段代码在Python的命令行中能正常工作,但当我把它集成到我的Django应用里时,就出现了一个UnicodeDecodeError
错误,错误信息是:
'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
我搞不明白为什么这个错误只在Django应用里出现,而在命令行中却没有。有人能帮我解答一下吗?
编辑:经过一些测试,我发现ActiveState网站上的一个食谱有个评论提到了一种解决方法:
body = CRLF.join([element.decode('string_escape') for element in L])
这个方法阻止了UnicodeDecodeError
错误的出现,但对某些图片造成了问题,所以对我来说并不是个解决方案 :/
奇怪的是,这个问题只发生在Django网页应用中,如果我从python manage.py shell
运行相同的命令,它就能正常工作,甚至不需要上面提到的解决方法。
有没有人知道命令行和网络服务器之间的环境差异可能导致这个问题吗?
1 个回答
4
你在从命令行测试代码时,可能都是用字符串(str
)的形式来提供所有的值,而Django应用程序返回的表单值(比如文件名)是以Unicode格式呈现的。这样一来,你的连接语句在把读取的文件内容从字符串转换成Unicode时,就会出错。
你可以检查一下添加到主体中的每个部分的类型,看看是不是这个原因,或者在连接之前,尝试把每个body
的部分都转换成字符串(str
):
body = [str(seg) for seg in body]
body = '\r\n'.join(body)