节点请求模块:将 XML 解析为 JSON
node request module: parsing XML as JSON
直到最近我一直在使用 node request 模块获取 XML 数据,然后 运行 通过 XML 到 JSON转换器。我偶然发现,如果我将 json: true
设置为选项(即使知道端点 returns XML,而不是 JSON),我实际上是在返回 JSON:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'Whosebug question ( } };
options.uri = 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=40.597&lon=-74.26';
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${JSON.stringify(body)}`);
});
上面调用returns JSON,而raw URL实际上是发送XML。果然,json: false
returned 数据是 XML:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'Whosebug question ( } };
options.uri = 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=40.597&lon=-74.26';
options.json = false; // <<--- the only difference in the request
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${body}`);
});
所以我想 "that's handy",直到我用 different URL that also returns XML 尝试了同样的技巧,在这种情况下,尽管使用了 returned 数据仍然是 XML相同的请求选项:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'Whosebug question ( } };
options.uri = 'https://graphical.weather.gov/xml/SOAP_server/ndfdXMLclient.php?whichClient=NDFDgen&lat=40.597&lon=-74.26&product=time-series&temp=tempSubmit=Submit';
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${body}`);
});
这里有什么区别?如何获得后一个请求 return JSON 格式的数据(这样我就可以避免自己将 XML 转换为 JSON 的步骤)?也许第一个示例中的端点可以检测到 JSON 被请求,它实际上是 return JSON 而不是 XML?
EDIT 奇怪的是,第一个请求现在 returning XML 而不是 JSON 即使 json: true
。所以也许这种行为取决于从端点发送的内容,甚至自从我几个小时前发布以来他们已经改变了这一点
所以现在行为是不可重复的,答案对你的特定问题不太有用,但我认为值得指出的是,当你在 request
模块上设置 json:true
时,它确实为您提供一些幕后花絮:
- 将接受 header 设置为 'application/json'
- 使用
JSON.parse()
解析响应 body
- 带有 body 的请求类型也会自动将 body 序列化为 JSON
- 带有 body 的请求类型也会得到 Content-Type header 添加为 'application/json'
所以也许他们确实改变了它,但我看到有很多 Web 服务会检测 content-type 以根据接受 header 发送并适当地响应某些集合有意义的类型(通常是 XML 或 JSON,但有时是 CSV、TXT、HTML 等)。
为了处理 XML 查询,我通常使用请求模块做这样的事情:
import parser from "xml2json";
const resp = await rp({
method: "POST",
url: 'some url',
form: {xml_query}, // set XML query to xml_query field
});
const parsedData = parser.toJson(resp, {
object: true, // returns a Javascript object instead of a JSON string
coerce: true, // makes type coercion.
});
直到最近我一直在使用 node request 模块获取 XML 数据,然后 运行 通过 XML 到 JSON转换器。我偶然发现,如果我将 json: true
设置为选项(即使知道端点 returns XML,而不是 JSON),我实际上是在返回 JSON:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'Whosebug question ( } };
options.uri = 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=40.597&lon=-74.26';
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${JSON.stringify(body)}`);
});
上面调用returns JSON,而raw URL实际上是发送XML。果然,json: false
returned 数据是 XML:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'Whosebug question ( } };
options.uri = 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=40.597&lon=-74.26';
options.json = false; // <<--- the only difference in the request
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${body}`);
});
所以我想 "that's handy",直到我用 different URL that also returns XML 尝试了同样的技巧,在这种情况下,尽管使用了 returned 数据仍然是 XML相同的请求选项:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'Whosebug question ( } };
options.uri = 'https://graphical.weather.gov/xml/SOAP_server/ndfdXMLclient.php?whichClient=NDFDgen&lat=40.597&lon=-74.26&product=time-series&temp=tempSubmit=Submit';
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${body}`);
});
这里有什么区别?如何获得后一个请求 return JSON 格式的数据(这样我就可以避免自己将 XML 转换为 JSON 的步骤)?也许第一个示例中的端点可以检测到 JSON 被请求,它实际上是 return JSON 而不是 XML?
EDIT 奇怪的是,第一个请求现在 returning XML 而不是 JSON 即使 json: true
。所以也许这种行为取决于从端点发送的内容,甚至自从我几个小时前发布以来他们已经改变了这一点
所以现在行为是不可重复的,答案对你的特定问题不太有用,但我认为值得指出的是,当你在 request
模块上设置 json:true
时,它确实为您提供一些幕后花絮:
- 将接受 header 设置为 'application/json'
- 使用
JSON.parse()
解析响应 body
- 带有 body 的请求类型也会自动将 body 序列化为 JSON
- 带有 body 的请求类型也会得到 Content-Type header 添加为 'application/json'
所以也许他们确实改变了它,但我看到有很多 Web 服务会检测 content-type 以根据接受 header 发送并适当地响应某些集合有意义的类型(通常是 XML 或 JSON,但有时是 CSV、TXT、HTML 等)。
为了处理 XML 查询,我通常使用请求模块做这样的事情:
import parser from "xml2json";
const resp = await rp({
method: "POST",
url: 'some url',
form: {xml_query}, // set XML query to xml_query field
});
const parsedData = parser.toJson(resp, {
object: true, // returns a Javascript object instead of a JSON string
coerce: true, // makes type coercion.
});