SuperAgentでXMLにアクセスした時にレスポンスのbodyやtextが取れなかったので調べてみました。
環境
- OS X El Capitan バージョン 10.11.3
- Node.js バージョン 5.5.0
- SuperAgent バージョン 1.7.2
- superagent-xml2jsparser バージョン 0.1.1
SuperAgent?
Super Agent is light-weight progressive ajax API crafted for flexibility, readability, and a low learning curve after being frustrated with many of the existing request APIs. It also works with Node.js!
単純にgetする
適当なXMLとして、復旧・復興支援制度データベース API V2 リファレンから、例にある http://api.r-assistance.go.jp/v2/supports.xml?appkey=0 にアクセスしてみます。
appkeyは「常に0を指定してください。」というAPI共通仕様のようなので、クエリーストリング(.query()
)で指定しています。
// a.js
const request = require('superagent');
(() => {
const url = 'http://api.r-assistance.go.jp/v2/supports.xml';
request.get(url)
.query({ appkey: 0 })
.end((err, res) => {
console.log(`res.text: ${res.text}`);
});
})();
実行してみるとundefinedになりました。
$ node a.js
res.text: undefined
buffer()をする
in later superagents you have to do
.buffer()
if the response is nottext/*
orapplication/json
res.text is undefined · Issue #129 · visionmedia/superagent · GitHub
ここでtjさんが「レスポンスのcontent-type
がtext/*
かapplication/json
以外の場合は.buffer()
をする」ように言っていました。
以下のところでもそういった内容が記載されていました。
To force buffering of response bodies as
res.text
you may invokereq.buffer()
. To undo the default of buffering for text responses such as “text/plain”, “text/html” etc you may invokereq.buffer(false)
.When buffered the
res.buffered
flag is provided, you may use this to handle both buffered and unbuffered responses in the same callback.
なので、.buffer()
をしてみます。
// a.js
const request = require('superagent');
(() => {
const url = 'http://api.r-assistance.go.jp/v2/supports.xml';
request.get(url)
.query({ appkey: 0 })
.buffer()
.end((err, res) => {
console.log(`res.text: ${res.text}`);
});
})();
実行してみるとtextが取れました。
$ node a.js
res.text: <supports_response xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><total_count>1136</total_count><supports><support><id>6039</id><name>住まいの復興給付金</name>
# ... 略
XMLをパースする
superagent-xml2jsparserを使うとJSONに変換した状態のものをbodyに入れてくれるようなので使ってみます。
// a.js
const request = require('superagent');
const xml2jsParser = require('superagent-xml2jsparser');
(() => {
const url = 'http://api.r-assistance.go.jp/v2/supports.xml';
request.get(url)
.query({ appkey: 0 })
.accept('xml')
.parse(xml2jsParser)
.buffer()
.end((err, res) => {
console.log(`res.body: ${JSON.stringify(res.body)}`);
});
})();
実行してみると使いやすいJSONに変換することができました。
$ node a.js
res.body: {"supports_response":{"$":{"xmlns:i":"http://www.w3.org/2001/XMLSchema-instance"},"total_count":["1136"],"supports":[{"support":[{"id":["6039"],"name":["住まいの復興給付金"],
# ... 略
終わり
superagent-xml2jsparserのUsageに次のようなコードが記載されていたんですけど、ここに.buffer()
と記載されていたらわかりやすかったと思いました。
request = require('superagent');
xml2jsParser = require('superagent-xml2jsparser');
request
.get('http://api.openweathermap.org/data/2.5/weather?q=Los Angeles&mode=xml')
.accept('xml')
.parse(xml2jsParser) // add the parser function
.end(function(err, res){
console.log(res.body)
})