我正在用netty开发一个http服务器。在某些情况下,服务器必须应答1x1透明像素。所以我用base64硬编码了一个gif透明像素,并用以下代码返回:

String pixel_string= new String (Base64.decodeBase64("R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="));
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
response.setContent(ChannelBuffers.copiedBuffer(pixel_string, CharsetUtil.UTF_8));

编辑:我还设置了内容类型:
response.setHeader(httpHeaders.names.content\u类型,
“图像/gif”);
在Chrome中,一切都很好。但是,firefox告诉我它不能显示像素(这对我的应用程序非常不利),因为像素数据无效。
经过多次调查,我终于找到了解决办法,把字符集改成了iso-8859-1。
response.setContent(ChannelBuffers.copiedBuffer(
            responseBuilder.pixel_string, CharsetUtil.ISO_8859_1));

我不明白为什么会这样,这让我觉得在某些情况下我可能会遇到麻烦。我试图更改firefox的首选项(将utf8作为默认设置),但变化不大。
为什么firefox接受iso-8859编码,而不是utf-8?我能改一下吗?会有人有一个问题的起源和如何确保它将工作,无论用户的设置线索?
谢谢

最佳答案

不管火狐是否接受编码。是你的服务器。
当您执行base64解码时,会生成一个包含一些字符的字符串…但你真正产生的是字节,然后你会以某种方式把它们看作字符。由于java字符串是一个包含utf-16字符串的容器,实际上,您要做的是获取每个字节,将其视为16位整数,并构造由这些代码单元组成的utf-16“字符串”。
但是当你想把这些都放到网络上时,你必须把字符串转换成字节,而copiedBuffer的参数说明了如何做到这一点。如果转换成utf-8,任何来自具有高位设置的字节的字符最终都将被编码为两字节的utf-8序列。另一方面,如果转换为iso-8859-1,则转换只会删除每个utf-16代码单元的高字节(在您的情况下,它始终为零)。
所以对iso-8859-1的转换产生的是base64解码得到的实际字节数组,而对utf-8的转换产生的是……根据确切的字节值,可能有意义,也可能没有意义。

09-30 13:54
查看更多