我使用json已经有一段时间了,问题是我解码的字符串被编码为Latin-1,我不能让它作为UTF-8工作。因此,一些字符显示不正确(例如,“显示为”)。
我在stackoverflow上读到过一些问题,但它们似乎不起作用。
我正在使用的json结构看起来像这样(它来自YouTube API):
...
"items": [
{
...
"snippet": {
...
"title": "Powerbeats Pro “Totally Wireless” Except when you need a wire",
...
}
}
]
我把它编码为:
response = await http.get(link, headers: {HttpHeaders.contentTypeHeader: "application/json; charset=utf-8"});
extractedData = json.decode(response.body);
dataTech = extractedData["items"];
然后我试着把第二行改成:
extractedData = json.decode(utf8.decode(response.body));
但这给了我一个错误的格式。所以我把它改为:
extractedData = json.decode(utf8.decode(response.bodyBytes));
这不会抛出错误,但也不能解决问题。
我希望数据像现在一样存储在dataTech中,但编码为UTF-8。我做错了什么?
3条答案
按热度按时间8cdiaqws1#
先说个题外话:UTF-8通常是一种 external 格式,并且通常由字节数组表示。它是您可能通过网络作为HTTP响应的一部分发送的内容。在内部,Dart将字符串存储为UTF-16代码点。
utf8
编码器/解码器在内部格式字符串和外部格式字节数组之间进行转换。这就是使用
utf8.decode(response.bodyBytes)
的原因;获取原始正文字节并将它们转换为内部字符串。(response.body
基本上也是这样做的,但是它根据响应头字符集选择bytes-〉string解码器。当这个字符集头丢失时(通常是这样),http
包选择Latin-1,如果您知道响应使用不同的字符集,您正在覆盖http
所做的(可能是错误的)选择,因为您知道这个特定的服务器总是发送UTF-8。(当然,它也可能不发送!)另一个在一旁道:在 request 上设置内容类型头很少有用。通常你不发送任何内容--所以它没有类型!而且这不会影响服务器将返回给你的内容类型或内容类型字符集。
accept
头可能就是你要找的。这是对服务器的一个提示,告诉你你想要返回什么类型的内容--但并非所有服务器都尊重它。那么,为什么特殊字符仍然不正确呢?在解码之前尝试打印
utf8.decode(response.bodyBytes)
。它在控制台中看起来正确吗?(对于此类问题,创建一个简单的Dart命令行应用程序非常有用;我发现在一个简单的10行Dart应用程序中设置断点和检查变量更容易。)尝试使用Wireshark之类的工具来捕获线路上的字节(同样,使用简单的Dart应用程序也很有用)。或者尝试使用Postman发送相同的请求并检查响应。你是如何尝试显示字符的。如果可能只是你使用的字体没有他们。
z9zf31ra2#
只需添加标题:
'Accept': 'application/json; charset=UTF-8';
它对我很有效pkwftd7m3#
我的标题看起来像:
响应的处理方式如下: