棘手的部分是将编码作为 null 传递来获取 Buffer 而不是字符串。
encoding - 用于响应数据的 setEncoding 的编码。
如果是null,则正文作为Buffer 返回。
—request
var request = require('request');
var legacy = require('legacy-encoding');
var requestSettings = {
method: 'GET',
url: 'http://www.chinanews.com/rss/scroll-news.xml',
encoding: null,
};
request(requestSettings, function(error, response, body) {
var text = legacy.decode(body, 'gb2312');
console.log(text);
});
再次,在后续问题的上下文中,“
有什么方法可以检测编码吗?”
我希望你所说的“检测”是指找到声明。 (……而不是猜测。如果您必须猜测,那么您的通信失败。)HTTP 响应标头 Content-Type 是通信编码的主要方式(如果适用于 MIME 类型)。一些 MIME 类型允许在内容中声明编码,因为服务器完全正确地遵循了这一点。
对于您的 RSS 响应。服务器发送Content-Type:text/xml。没有编码覆盖。并且内容的 XML 声明是<?xml version="1.0" encoding="gb2312"?> XML 规范具有查找此类声明的过程。它基本上相当于用不同的编码读取,直到 XML 声明变得可以理解,然后用声明的编码重新读取。
var request = require('request');
var legacy = require('legacy-encoding');
var convert = require('xml-js');
// specials listed here: https://www.w3.org/Protocols/rfc1341/4_Content-Type.html
var charsetFromContentTypeRegex = (/charset=([^()<>@,;:\"/[\]?.=\s]*)/i).compile();
var requestSettings = {
method: 'GET',
url: 'http://www.chinanews.com/rss/scroll-news.xml',
encoding: null,
};
request(requestSettings, function(error, response, body) {
var contentType = charsetFromContentTypeRegex.exec(response.headers['content-type'])
var encodingFromHeader = contentType.length > 1 ? contentType[1] : null;
var doc = convert.xml2js(body);
var encoding = doc.declaration.attributes.encoding;
doc = convert.xml2js(
legacy.decode(body, encodingFromHeader ? encodingFromHeader : encoding));
// xpath /rss/channel/title
console.log(doc.elements[1].elements[0].elements[0].elements[0].text);
});