【发布时间】:2014-11-09 23:49:41
【问题描述】:
我有一个 HTTP 响应标头,其中包含 ISO-8859-1 字符(é、0x39)。下面是显示 HTTP 响应的原始数据包捕获,底部第二行:
00000000 48 54 54 50 2f 31 2e 30 20 32 30 30 20 4f 4b 0d HTTP/1.0 200 OK.
00000010 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 61 .Content -Type: a
00000020 75 64 69 6f 2f 61 61 63 70 0d 0a 69 63 79 2d 62 udio/aac p..icy-b
00000030 72 3a 34 30 0d 0a 69 63 79 2d 67 65 6e 72 65 3a r:40..ic y-genre:
00000040 4a 61 7a 7a 20 4c 6f 75 6e 67 65 20 43 61 66 65 Jazz Lou nge Cafe
00000050 0d 0a 69 63 79 2d 6e 61 6d 65 3a 43 61 66 e9 20 ..icy-na me:Caf.
00000060 64 65 20 50 61 72 69 73 20 2d 20 52 41 44 49 4f de Paris - RADIO
标题应该是:
icy-name:Café de Paris
我正在做一个非常简单的http.get() 请求:
http.get('http://example.com/streamUrl', function (res) {
console.log(res.headers);
});
在我的控制台上,我看到:
'icy-name': 'Caf� de Paris',
然后我尝试将字符串转换为缓冲区:
console.log(new Buffer(res.headers['icy-name']));
// <Buffer 43 61 66 ef bf bd 20 64 65 20 50 61 72 69 73 ... >
原来的字符0xe9似乎在转换到我的Buffer之前或者在转换过程中已经丢失了。然后,我认为iconv-lite 可能会有所帮助:
var iconv = require('iconv-lite');
iconv.extendNodeEncodings();
console.log( (new Buffer(res.headers['icy-name'], 'latin1')).toString('utf8') );
// "Caf? de Paris" with a literal question mark, `0x3F`.
我怀疑在我的代码获得响应标头值之前损坏已经造成。我的问题:
- 我的假设是否正确,即字符串首先被 Node.js 的 HTTP 客户端错误解释?
- 是否可以配置 Node.js 以正确处理 HTTP 响应? RFC5987 表示 HTTP 响应的默认字符集是 ISO-8859-1。
- 如果没有办法让 Node.js 正常运行,有没有办法撤消转换损坏,恢复原始 ISO-88591-1 字符串,然后转换为 UTF-8?
【问题讨论】:
-
而且您确定所有文件都保存为 UFT8 等。
-
@adeneo 它与文件没有任何关系。我说的是 HTTP 响应标头本身。此响应中的实际数据是二进制的,无需担心。其他 HTTP 客户端已经能够成功处理响应标头。此外,有问题的数据是 ISO-88591-1,而不是 UTF-8。我需要转换为 UTF-8,但我感觉 ISO-88591-1 字符串一开始就没有正确处理。
-
@adeneo 我什么都没设置。我的 Node.js 代码是客户端,而不是服务器。我正在访问其他服务器上的标头,这不是我的代码,也不是用 Node.js 构建的。即使是这样,标准(据我所知)规定 HTTP 响应标头默认情况下应为 ISO-8895-1。您可以从十六进制转储中看到响应数据在通过网络发送时很好。我也知道其他 HTTP 客户端可以正确处理响应标头。数据的来源不是问题。问题与 Node.js 或我的应用程序有关。
标签: javascript node.js http character-encoding http-headers