AngularJS TIPS
JSON形式のWeb APIにアクセスするには?($http)
Web APIと通信する際に問題となるクロスドメイン制約を回避するために使われるテクニック「JSONP」を、AngularJSで実現するための基本的な方法を説明する。
XMLHttpRequest
(XHR)オブジェクトのよく知られた制約として、クロスドメイン制約があります。クロスドメイン制約とは、(デフォルトでは)JavaScriptからドメインを超えて通信できない制約のことです。$http
サービスもまた、内部的にはXHRオブジェクトを利用していますので、この制約からは自由ではありません。
クロスドメイン制約を回避するテクニックにはさまざまなものがありますが、その中でも古典的で、よく利用されているのがJSONP(JSON with Padding)です。JSONPとは、その名の通り、JSON(=JavaScriptのオブジェクトリテラル形式になぞらえたデータ)でデータを交換する仕組みのこと。内部的にもXHRオブジェクトを利用しませんので、クロスドメイン制約からも自由です。
そして、$http
サービスでもjsonp
メソッド(またはmethod
パラメーターにjsonp)を利用することで、JSONPをごくシンプルな手順で利用できます。本稿では、「OpenWeatherMap」で提供されるWeb APIを利用して、指定された都市の現在の天気を表示してみます。まずは、具体的なコードを見てみましょう。
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<form>
<select ng-model="city">
<option value="1850147">東京</option>
<option value="1856057">名古屋</option>
<option value="1853909">大阪</option>
<option value="1907125">福岡</option>
</select>
<button ng-click="onclick()">検索</button>
</form>
<img ng-src="{{weather}}" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script>
angular.module('myApp', [])
.controller('MyController', ['$scope', '$http', function($scope, $http) {
$scope.onclick = function() {
$http.jsonp('http://api.openweathermap.org/data/2.5/weather',
{
params: {
callback: 'JSON_CALLBACK', // 1コールバック関数の名前
id: $scope.city, // 都市コード
APPID: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' // アプリケーションキー
}
}
)
// 2Web APIの結果に基づいて天気アイコンを表示
.success(function(data) {
$scope.weather = 'http://openweathermap.org/img/w/'
+ data.weather[0].icon +'.png';
})
.error(function(err) {
console.log(err);
});
};
}]);
</script>
</body>
</html>
|
$http.jsonp
メソッドの構文それ自体は、別稿「TIPS:サーバーサイドと非同期通信するには?」で解説した$http
サービスと同様です。ここでポイントとなるのは2点です。
1コールバック関数の名前は「JSON_CALLBACK」
jsonp
メソッドでは、パラメーター(params
-callback
パラメーター)としてコールバック関数の名前を指定しなければなりません。この場合、コールバック関数とは、Web APIから応答を得られた時に内部的に呼び出される関数のことです。関数名は固定で「JSON_CALLBACK」とします。
[Note]OpenWeatherMapのその他のパラメーター
params
パラメーターに渡している、その他のパラメーターは、「OpenWeatherMap」固有のパラメーターです。
id
: 都市コードを表します。利用できる都市コードは、こちらからダウンロードできます。APPID
: APIを利用するためのキーです。「OpenWeatherMap」からアカウントを作成することで取得できます。
実際にサンプルを動作するに際しては、自分で取得したコードに置き換えてください。
まずは、この2個が主となりますので、その他に利用できるパラメーターについては、「Current weather data」から確認してください。
2成功コールバック関数の引数に渡されるのはJavaScriptオブジェクト
成功コールバック関数の引数data
(=結果)には、デコード済みのJavaScriptオブジェクトが渡されます。JSON文字列ではありませんので、angular.fromJSON
メソッドなどによるデコード処理は不要です。
オブジェクトの構造は、もちろん、Web APIによって異なります。例えば、「OpenWeatherMap」であれば、以下のようなオブジェクトを返します(主なものを抜粋しています)。
/ | ||
---|---|---|
name | …… 地名 | |
coord | ||
├ lon | …… 経度 | |
└ lat | …… 緯度 | |
sys | ||
├ country | …… 国コード | |
├ sunrise | …… 日の出時間 | |
└ sunset | …… 日の入り時間 | |
weather(配列) | ||
├ main | …… 天気 | |
└ icon | …… 天気を表すアイコン | |
main | ||
├ temp | …… 気温 | |
├ humidity | …… 湿度 | |
├ pressure | …… 気圧 | |
├ temp_min | …… 最低気温 | |
└ temp_max | …… 最高気温 | |
wind | ||
├ speed | …… 風速 | |
└ deg | …… 風向き | |
rain | ||
└ "3h | …… 直近3時間の降水量 |
ここでは、data.weather[0].icon
で天気を表すアイコン(ベース名)を取得し、これをもとに<img>
要素に反映させることで、指定された都市の天気を画像表示しています。
API:$http カテゴリ:ng(コアモジュール) > service(サービス)
※以下では、本稿の前後を合わせて5回分(第35回~第39回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
35. サーバーサイドと非同期通信するには?($http)
AngularJSでサーバーサイドのWeb APIと非同期通信する方法を説明。また、ログの種類や、ショートカットメソッドについても紹介する。
36. サーバーサイドとHTTP POSTで非同期通信するには?($http)
AngularJSでHTTP POSTで非同期通信する方法を説明。また、送信データをJSONではなくjQuery形式にする方法や、PHPでJSONデータをデコードする方法も紹介する。
37. 【現在、表示中】≫ JSON形式のWeb APIにアクセスするには?($http)
Web APIと通信する際に問題となるクロスドメイン制約を回避するために使われるテクニック「JSONP」を、AngularJSで実現するための基本的な方法を説明する。
38. 指定された時間の経過で処理を実行するには?($interval/$timeout)
ミリ秒単位で処理を実行できる、いわゆる「タイマー」である$intervalサービスの基本的な使い方を解説。また、一定時間後に処理を実行する$timeoutサービスについても説明する。