DartでJSONP

Seth Ladd’s Blog: JSONP with DartにJSONPをDartで使う方法について説明がされています。具体的にどうすれば良いか、確認をしてみました。

Dartプログラムは次のようになります。Dart Editor で新規アプリケーション作成のウィザードからプログラムを生成して、修正していけばいいでしょう。JSONデータの展開にあたっては、parseメソッドを使います。ここでは、サンプルデータを使っていくつか要素へのアクセス方法についても示してあります。実際のプログラムでは、取り出したいJSONデータに合わせればいいでしょう。

#import('dart:html');
#import('dart:json');

dataReceived(MessageEvent e) {
  var data = JSON.parse('{"responseData": "sample1"}');
  String s = "sample1 ... " + data['responseData'];
  data = JSON.parse('{"responseData": {"results":"sample2"}}');
  s =  s + "<br />sample2 ... " + data['responseData']['results'];
  data = JSON.parse('{"responseData": {"results": {"moreResultsUrl":"http://example.jp/"}}, "responseStatus": 200}');
  s =  s + "<br />sample3 ... " + data['responseData']['results']['moreResultsUrl'];
  data = JSON.parse('''
   {
    "responseData": {
      "results":[{"content":"c", "url":"http://"}],
      "cursor":{"moreResultsUrl":"http://example.jp/"}
    }, 
    "responseStatus": 200
   }
''');
  s =  s + "<br />sample4 responseStatus ... " + data['responseStatus'];
  s =  s + "<br />sample4 moreResultsUrl ... " + data['responseData']['cursor']['moreResultsUrl'];
  data = JSON.parse(e.data);
  s =  s + "<br />e.data responseStatus ... " + data['responseStatus'];
  s =  s + "<br />e.data results[0] url ... " + data['responseData']['results'][0]['url'];
  document.query('#status').innerHTML = s;
}
void main() {
  window.on.message.add(dataReceived);
  
  ScriptElement script = new Element.tag("script");
  script.src = "https://ajax.googleapis.com/ajax/services/search/news?v=1.0&q=barack%20obama&callback=callbackForJsonpApi";
  document.body.elements.add(script);
}

実際にJSONP経由のデータを解析しているのは、data = JSON.parse(e.data) のところです。dataReceived()関数はどうやって呼ぶかというと、少々トリッキーなことをしています。

まず、メッセージを監視するように、「window.on.message.add(dataReceived)」として、dataReceived()関数を登録しています。動的にJSONP APIを呼び出したいことが多いはずなので、ScriptElementを使ってタグを動的に生成しています。このAPIを指定するURIで、「callback=callbackForJsonpApi」とJavaScriptの関数を指定しています。

callbackForJsonpApiというJavaScriptの関数は、HTML側に用意しておきます。この関数がJSONP APIから呼び出されるので、ここに来た値をdataReceived関数へ伝搬させるために、postMessage()を使って、windowへメッセージをpostします。

<script type="text/javascript">
function callbackForJsonpApi(s) {
  window.postMessage( JSON.stringify(s), '*');
}
</script>

今回用意したHTMLでは、JSONPで取り出した値について結果表示をするように、Dartプログラムにあわせて、下記のようにしました。

<html>
  <head>
    <title>jsonp</title>
  </head>
  <body>
    <h1>jsonp</h1>
    <h2 id="status">dart is not running</h2>
<script type="text/javascript">
function callbackForJsonpApi(s) {
  window.postMessage( JSON.stringify(s), '*');
}
</script>
    <script type="application/dart" src="jsonp.dart"></script>
    <script src="http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"></script>
  </body>
</html>

実行すると、次のような結果になりました。

jsonp

sample1 ... sample1
sample2 ... sample2
sample3 ... http://example.jp/
sample4 responseStatus ... 200
sample4 moreResultsUrl ... http://example.jp/
e.data responseStatus ... 200
e.data results[0] url ... http%3A%2F%2Fwww.afpbb.com%2Farticle%2Flife-culture%2Freligion%2F2866309%2F8663407%3Fctm_campaign%3Dtxt_topics

面白いですねぇ。

同じタグの記事: Dart
同じタグの記事: Linux
同じカテゴリの記事: Program