サンプル・プログラム
WebAPI利用イメージ
クライアント(ブラウザ)からインターネットを経由し、WikipediaやAmazon、Googleといったクラウドの WebAPI を利用する。
クライアントから検索キーワードなどをGET/POSTなどのhttp通信で WebAPI へ送信すると、結果が XML や JSON の形で返ってくる。WebAPI の裏側にはデータベースなどのシステムがあるかもしれないが、クライアントからはそれらを意識しないで済む。
郵便番号→住所検索
利用は無償だが、このWebAPIの 利用規約を遵守すること。
URL |
---|
https://api.thni.net/jzip/X0401/JSONP/{1}/{2}.js |
フィールド名 | 要否 | 内 容 |
---|---|---|
1 | 必須 | 郵便番号(上3桁) |
2 | 必須 | 郵便番号(下4桁) |
71: /**
72: * ZIP SEARCH API SERVICE API:郵便番号→住所検索(JSONP)
73: * @param String zip1 郵便番号(ハイフンの前 3桁)
74: * @param String zip2 郵便番号(ハイフンの後 4桁)
75: * @return String リクエストURL
76: */
77: function getURL_Zip2Address(zip1, zip2) {
78: let url = 'https://api.thni.net/jzip/X0401/JSONP/' + zip1 + '/' + zip2 + '.js';
79:
80: return url;
81: }
まず、入力した郵便番号をハイフンで3桁と4桁に分離する。これには split メソッドを利用した。
次に、WebAPI を非同期呼び出しするために XMLHttpRequest オブジェクトを生成する。これは、WebAPI のような非同期通信を行う Ajax(Asynchronous JavaScript + XML)通信を行うときに使うオブジェクトだ。XMLの名前が付いているが、JSONやJSONPでも利用できる。
ここで、JavaScriptには、同一オリジンのリソースにしかアクセスできないという制限 SOP(Same-Origin Policy;同一生成元ポリシー)が課されている。同一オリジンというのは、同じドメイン、同じポート番号であることを指す。
SOPはセキュリティ対策の一環で、JavaScriptが悪意のあるスクリプトを実行したり、異常なデータを参照することを回避するための仕組みである。
しかし、WebAPI にアクセスするには、この SOP が邪魔になる。そこで、サーバ側で特殊なHTTPヘッダ項目を追加することで、送り出したWebページ上のスクリプトがWebブラウザから別のサーバへアクセスできるようにする CORS(Cross-Origin Resource Sharing;クロスオリジンリソース共有)が施されていることが望ましい。
だが、今回利用する ZIP SEARCH API SERVICE を含め、CORS に対応している WebAPI は少ない。
ここでは次善の策として、JSONPを使って SOP を回避する。
具体的には、2つのscriptを動的に追加する。
1つは、WebAPI そのものを srcとするscriptだ。これにより、scriptが WebAPI と同一オリジンで実行されると見せかけることになる。
2つめは、JSONPで実行されるscriptを追加する。JSONP は、JSONデータを解析する関数を追加したデータ形式である。ZIP SEARCH API SERVICE ではJSOP実行関数は ZipSearchValue 固定だ。
scriptの追加には appendChild メソッドを用いた。エラー発生時には、console.logとHTMLにエラーを出力する。
JSONP実行関数は、JSON形式の応答データをそのままHTMLの要素に代入するだけである。
最後に、都道府県名、市町村名、町名などを結合し、クリップボードにコピーできるようにした。
このプログラムは、よくある会員登録で郵便番号ボタンをクリックすると自動的に住所が入力されるGUIに応用できる。
Wikipedia検索
URL |
---|
https://ja.wikipedia.org/w/api.php |
フィールド名 | 要否 | 内 容 |
---|---|---|
format | 省略可 | xml, json, yaml等 |
callback | 省略可 | コールバック関数名 |
action | 必須 | 操作:ここではquery |
prop | 省略可 | action固有のパラメータ。記事の各構成要素を取得する。ここではextractsを指定し、サマリを抽出する。 |
explaintext | 省略可 | 出力をHTMLではなくプレーンテキストにする。 |
redirects | 省略可 | リダイレクト記事を含める。 |
titles | 必須 | 見出し検索語。 |
68: /**
69: * Wikipedia API:サマリのリクエストURLを取得する
70: * @param String query 検索キーワード
71: * @return String リクエストURL
72: */
73: function getURL_WikipediaAPI_summary(query) {
74: let url = 'https://ja.wikipedia.org/w/api.php?format=json&callback=callback&&action=query&prop=extracts&exintro&explaintext&redirects=1&titles=' + encodeURI(query);
75:
76: return url;
77: }
前述の getURL_Zip2Address と異なり、パラメータを GETで渡す。
Wikipedia API には明示的にJSONP呼び出しはないが、コールバック関数を指定することによって同様の処理ができる。
留意点すべきは、応答で得られるJSONオブジェクトのページIDが可変である点。
IEでも動作するよう、Object.keys を利用し、応答で得られるJSONオブジェクト result.query.pages の最初の要素を取得する。これがページIDである。
ページIDから目的のサマリーが存在するかどうかを typedef 演算子で調べ、無ければHTMLとconsole.logにエラー出力する。
コラム:CORS問題
あるクライアントまたはすべてのクライアントに CORS を許可するには、サーバ側で Access-Control-Allow-Origin ヘッダを送信する必要がある。
自サーバやレンタルサーバであれば、この設定ができるだろうが、Wikipediaのような既存クラウドサービスで設定することはできない。そこで今回は、JSONPを使って回避をしている。
ただし、CORS 導入の目的から明らかなように、JSONPを使ったり CORS を回避することは、プログラムが脆弱性リスクを抱えることになる。
参考サイト
- ZIP SEARCH API SERVICE 「JIS X0401」対応版
- API:メイン ページ:MediaWiki
- PHPで「Wikipedia API」を利用する:ぱふぅ家のホームページ
- PHPで郵便番号から住所を求める:ぱふぅ家のホームページ
JavaScriptを使って、今回は、ZIP SEARCH API SERVICE を使って郵便番号を住所に変換するプログラムと、Wikipedia API を使ってWikipediaの見出し語検索を行うプログラムを作ってみよう。