Python 为什么string.encode(';utf-8';)是真的!=字节(映射(ord,字符串))? < >我们认为代码>字节(MAP(ORD,String))< /代码>使用什么编码?为什么string.encode('utf-8')有时是真的字节(映射(ord,字符串))
当客户端javascript与Django 1.5(Python 3)应用程序交互时,我遇到了这个问题 基本上,我使用ajax和jDataView将mp3文件作为字符串上传(我找不到直接上传文件的解决方案)。我使用jDataView将文件转换为字符串。在Django应用程序中,当我保存文件时,它会更改大小。但是,如果不使用Python 为什么string.encode(';utf-8';)是真的!=字节(映射(ord,字符串))? < >我们认为代码>字节(MAP(ORD,String))< /代码>使用什么编码?为什么string.encode('utf-8')有时是真的字节(映射(ord,字符串)),python,python-3.x,encoding,utf-8,bytearray,Python,Python 3.x,Encoding,Utf 8,Bytearray,当客户端javascript与Django 1.5(Python 3)应用程序交互时,我遇到了这个问题 基本上,我使用ajax和jDataView将mp3文件作为字符串上传(我找不到直接上传文件的解决方案)。我使用jDataView将文件转换为字符串。在Django应用程序中,当我保存文件时,它会更改大小。但是,如果不使用string.encode('utf-8')I使用bytes(map(ord,string))文件保存良好。为什么呢?为什么string.encode('utf-8')!=字节
string.encode('utf-8')
I使用bytes(map(ord,string))
文件保存良好。为什么呢?为什么string.encode('utf-8')!=字节(映射(ord,字符串))
我的客户端代码如下所示:
function send(file) {
var reader = new FileReader();
reader.onload = function(event) {
var self = this;
$.ajax({
url: 'upload/',
type: 'POST'
data: {contents: (new jDataView(self.result)).getString()}
});
}
reader.readAsArrayBuffer(file);
}
我的视图接收的数据如下所示:
def upload(request):
contents = request.POST.get('contents')
track = Track.objects.all[0] # For testing only
contents = bytes(map(ord, contents))
track.file.save('file.mp3', ContentFile(contents))
我检查了,JS代码和Python代码中的内容都是一样的。它们有相同的字节长度,从屏幕上的前几个和最后几个字符判断,它们似乎有相同的内容
如果我将代码更改为
def upload(request):
contents = request.POST.get('contents')
track = Track.objects.all[0] # For testing only
contents = contents.encoding('utf-8')
track.file.save('file.mp3', ContentFile(contents))
文件大小会更改,不再是有效的mp3文件。UTF-8不会将Unicode代码点直接映射到字节。这仅适用于范围为U+0000到U+007F的ASCII码点。超出该范围,UTF-8在每个代码点上使用2个或更多字节:
>>> '\u007f'.encode('utf8')
b'\x7f'
>>> '\u0080'.encode('utf8')
b'\xc2\x80'
您考虑的是拉丁-1编码,其中代码点U+0000到U+00FF直接映射到字节:
>>> string = ''.join([chr(i) for i in range(0x100)])
>>> string.encode('latin-1') == bytes(map(ord, string))
True
您可以在存储二进制数据之前对二进制数据进行base64编码,也可以升级到Django 1.6或更高版本,以使用。UTF-8不将Unicode代码点直接映射到字节。这仅适用于范围为U+0000到U+007F的ASCII码点。超出该范围,UTF-8在每个代码点上使用2个或更多字节:
>>> '\u007f'.encode('utf8')
b'\x7f'
>>> '\u0080'.encode('utf8')
b'\xc2\x80'
您考虑的是拉丁-1编码,其中代码点U+0000到U+00FF直接映射到字节:
>>> string = ''.join([chr(i) for i in range(0x100)])
>>> string.encode('latin-1') == bytes(map(ord, string))
True
您可以在存储二进制数据之前对二进制数据进行base64编码,也可以升级到Django 1.6或更高版本,以使用。值得注意的是,如果您确实需要通过纯文本通道传递任意字节的数据(而不仅仅是人为地将某个对象称为纯文本通道,即使它处理任意字节,因为Django 1.5的限制,OP似乎在这里这样做,但我不确定……),正确的答案通常是@abarnert:这似乎更多的是关于浏览器-Django post handler数据传输。谢谢。这正是我想要的。我不完全理解编码,所以这很有用。值得注意的是,如果您确实需要通过纯文本通道传递任意字节数据(而不仅仅是人为地将某个对象称为纯文本通道,即使它处理任意字节,因为Django 1.5的限制,OP似乎在这里这样做,但我不确定……),正确答案通常是@abarnert:看来这更多的是关于浏览器-Django post handler数据传输。谢谢。这正是我想要的。我不完全理解编码,所以这很有帮助。