AI生成コンテンツ / AI-generated content
出先でスマートフォンを取り出し、いま自分がいる場所の1週間の天気を確かめたくなることがある。本項では、気象庁が公開している気象庁防災情報XMLから週間天気予報を取り寄せ、現在地に近い地点の予報を7日分のカードで表示する「天気予報ツール」(weeklyWeather.html)を作る。全国47都道府県・64地点に対応し、位置情報が使えないときは地方・都道府県・都市名のプルダウンで選べる。
HTTPサーバーもNode.jsも使わず、1つのHTMLファイルをブラウザで開くだけで動く。通信するのは気象庁のXMLだけで、現在地は保存も送信もしない。位置情報や通信は、許可されない、届かない、遅れるといった失敗が日常的に起きる。Webサーバーに頼らずブラウザだけで外部のデータを取り込む場合に何を考え、失敗したときにどう止まるかを、実際のコードを例に順を追って説明する。

作成の動機に続き、気象庁XMLの構造、Geolocation APIによる現在地の取得、緯度・経度から最寄りの地点を求める距離計算、fetchによる取得、AbortControllerによる時間切れの処理、DOMParserによるXMLの解析、古い結果で表示を上書きしない工夫、通信先を気象庁だけに絞る仕組み、予報カードの描画を順に解説する。最後にCodexへ渡したプログラム仕様書を示す。
作成の動機に続き、気象庁XMLの構造、Geolocation APIによる現在地の取得、緯度・経度から最寄りの地点を求める距離計算、fetchによる取得、AbortControllerによる時間切れの処理、DOMParserによるXMLの解析、古い結果で表示を上書きしない工夫、通信先を気象庁だけに絞る仕組み、予報カードの描画を順に解説する。最後にCodexへ渡したプログラム仕様書を示す。
目次
作成の動機
旅先や出張先では、天気を知りたい場所が自宅と違う。天気予報のアプリやサイトは数多くあるが、広告が多い、会員登録を求められる、見たい情報(降水確率と気温)までたどり着くのに画面を何度も切り替える、といった不満が残る。知りたいのは「今いる場所の、この1週間の天気」だけである。

天気のデータそのものは、気象庁が気象庁防災情報XMLとして公開している。誰でも取得でき、天気予報の元になる情報が機械で読める形で並んでいる。このXMLを読んで必要な項目だけを表示するツールを1つ作れば、スマートフォンからも使える自分専用の天気予報になる。著者はこのXMLを、サーバー側のPHPプログラムで読み取る方法を「PHPで天気予報を求める」で紹介している。本項では同じ元データを、サーバーを使わずブラウザのJavaScriptだけで読む。
天気のデータそのものは、気象庁が気象庁防災情報XMLとして公開している。誰でも取得でき、天気予報の元になる情報が機械で読める形で並んでいる。このXMLを読んで必要な項目だけを表示するツールを1つ作れば、スマートフォンからも使える自分専用の天気予報になる。著者はこのXMLを、サーバー側のPHPプログラムで読み取る方法を「PHPで天気予報を求める」で紹介している。本項では同じ元データを、サーバーを使わずブラウザのJavaScriptだけで読む。
完成した天気予報ツール(バージョン0.1.0の画面。東京の7日間の予報を表示)
| 項目 | 内容 |
|---|---|
| データの出どころ | 気象庁防災情報XML(府県週間天気予報)。予報の数値はプログラムに埋め込まず、開くたびに取り寄せる |
| 地点の選び方 | 現在地から最寄りの地点を自動選択、または地方・都道府県・都市名のプルダウンで手動選択 |
| 対応地点 | 全国47都道府県の64地点。すべての市町村を選べるわけではない |
| 表示するもの | 天気、降水確率、最高・最低気温、予報の信頼度を最大7日分 |
| 通信 | 気象庁のXMLだけ。現在地の座標は保存も送信もしない |
| 動かし方 | 1つのHTMLファイルをブラウザで開く。HTTPサーバー・Node.js・外部ライブラリは不要 |
「3.9 QRコード生成・読取ツール」までのツールは、基本的に外部と通信しなかった。「2.6 クラウドAPIを利用する」でWikipedia APIを扱ったが、あのときは通信そのものを試す段階であった。今回は、外から取り込んだデータをそのまま画面に出す、という実用的なツールとしての通信を初めて本格的に扱う。取り込んだデータは、相手の都合で形が変わることも、途切れることも、遅れることもある。その前提で、プログラムをどう守るかが、本項の主題の1つになる。
気象庁防災情報XMLとは
気象庁防災情報XMLは、気象庁が防災に関わる情報を、コンピュータが読める形で公開しているデータである。天気予報だけでなく、警報・注意報、地震、火山、台風など、多くの種類がある。気象庁のサイトで見る天気予報の画面も、こうしたデータを元に作られている。本ツールが使うのは、そのうち府県週間天気予報と呼ばれる種類である。

ここでXMLという書式を説明しておく。XMLは、データに「これは何の値か」という項目名を付けて書く書式である。項目名はタグと呼び、<Weather>雨</Weather> のように、値を開始タグと終了タグで挟んで書く。この例は「Weather(天気)の値が『雨』である」ことを表す。タグの中に別のタグを入れ子にできるので、「福岡県の、10月26日の、天気は雨」のように階層のあるデータを表せる。HTMLとよく似た見た目をしているが、HTMLが「画面にどう見せるか」を決めるのに対して、XMLは「データの意味」を伝えるための書式である。「2.6 クラウドAPIを利用する」で出てきたJSONも同じ目的の書式で、JSONのほうが短く書け、XMLは項目名を1つずつ書くぶん長くなる。気象庁防災情報XMLはXMLで配信されている。

気象庁XMLの取得は、2段階になっている。まず、どのファイルがいつ配信されたかを並べた配信一覧(Atomフィードという形式のXML)を取得する。次に、一覧の中から目的のファイルのURLを探し、そのファイルを取得する。
ここでXMLという書式を説明しておく。XMLは、データに「これは何の値か」という項目名を付けて書く書式である。項目名はタグと呼び、<Weather>雨</Weather> のように、値を開始タグと終了タグで挟んで書く。この例は「Weather(天気)の値が『雨』である」ことを表す。タグの中に別のタグを入れ子にできるので、「福岡県の、10月26日の、天気は雨」のように階層のあるデータを表せる。HTMLとよく似た見た目をしているが、HTMLが「画面にどう見せるか」を決めるのに対して、XMLは「データの意味」を伝えるための書式である。「2.6 クラウドAPIを利用する」で出てきたJSONも同じ目的の書式で、JSONのほうが短く書け、XMLは項目名を1つずつ書くぶん長くなる。気象庁防災情報XMLはXMLで配信されている。
気象庁XMLの取得は、2段階になっている。まず、どのファイルがいつ配信されたかを並べた配信一覧(Atomフィードという形式のXML)を取得する。次に、一覧の中から目的のファイルのURLを探し、そのファイルを取得する。
配信一覧の実体は、regular_l.xmlというXMLファイルである。著者が2026年(令和8年)10月24日に確かめた時点で、ファイルの大きさは約4.6MB(4,648,854バイト)あった。一覧の1件ずつがentryというタグで表され、その中に種別名(title)、予報XMLのURL(id)、発表日時(updated)、発表元(author)が入っている。発表日時は世界標準時(UTC)で書かれており、末尾の Z がその印である。日本時間より9時間遅れた時刻になる点に注意が要る。

予報XMLのファイル名は、たとえば 20261024014928_0_VPFW50_400000.xml のように、発表時刻を表す14桁の数字、種別を表すVPFW50(府県週間天気予報)、そして末尾の6桁の数字(福岡県は400000)でできている。本ツールは、一覧から「ファイル名が _VPFW50_ と地点の6桁の数字で終わる entry」を探し、複数あれば発表日時が最も新しいものを選ぶ。

本ツールは、全国47都道府県の64地点を、あらかじめHTMLの中に埋め込んである。1地点ごとに、地方、都道府県、都市名、この6桁の数字、予報区域コード、観測地点コード、緯度、経度を持たせた表である。この地点表は、著者が「PHPで天気予報を求める」で公開している対応表(2026年6月6日版)を元にしている。予報の数値そのものは埋め込まず、開くたびに気象庁から取り寄せる。一方、地点の名前や緯度経度は変わることがほとんどないため、あらかじめ持たせても問題が少ない。この使い分けは、データを扱うときの基本的な考え方である。
予報XMLのファイル名は、たとえば 20261024014928_0_VPFW50_400000.xml のように、発表時刻を表す14桁の数字、種別を表すVPFW50(府県週間天気予報)、そして末尾の6桁の数字(福岡県は400000)でできている。本ツールは、一覧から「ファイル名が _VPFW50_ と地点の6桁の数字で終わる entry」を探し、複数あれば発表日時が最も新しいものを選ぶ。
本ツールは、全国47都道府県の64地点を、あらかじめHTMLの中に埋め込んである。1地点ごとに、地方、都道府県、都市名、この6桁の数字、予報区域コード、観測地点コード、緯度、経度を持たせた表である。この地点表は、著者が「PHPで天気予報を求める」で公開している対応表(2026年6月6日版)を元にしている。予報の数値そのものは埋め込まず、開くたびに気象庁から取り寄せる。一方、地点の名前や緯度経度は変わることがほとんどないため、あらかじめ持たせても問題が少ない。この使い分けは、データを扱うときの基本的な考え方である。
現在地を取得する
AI生成コンテンツ / AI-generated content
「今いる場所」を知るために、ブラウザにはGeolocation API(ジオロケーション API)という標準機能がある。JavaScriptから navigator.geolocation.getCurrentPosition() を呼ぶと、ブラウザが端末の位置を調べて、緯度と経度を返してくる。スマートフォンならGPSや周囲のWi-Fi・携帯電話の基地局の情報、パソコンならWi-FiやIPアドレスの情報から位置が推定される。位置の調べ方はブラウザとOSが決めるもので、JavaScriptのプログラムは結果だけを受け取る。
位置情報は個人のプライバシーに深く関わる。そのためブラウザは、初めて呼び出されたとき、利用者に「この場所の位置情報の利用を許可しますか」と確認する。許可されなければ、プログラムは位置を知ることができない。
本ツールが位置を取得する部分を、要点だけ抜き出して示す。
weeklyWeather.html(現在地の取得・抜粋)
navigator.geolocation.getCurrentPosition((position) => {
const { latitude, longitude } = position.coords;
// 最も近い地点を探して、予報を表示する(次項)
}, (error) => {
// 許可されなかった、特定できなかった、時間切れのいずれか
const reasons = {
1: '位置情報の利用が許可されませんでした。',
2: '現在地を特定できませんでした。',
3: '位置情報の取得が時間切れになりました。',
};
}, { enableHighAccuracy: false, timeout: 12000, maximumAge: 60000 });
getCurrentPositionには3つの引数を渡す。1つめは位置が取得できたときに呼ばれる関数で、緯度(latitude)と経度(longitude)が入った結果を受け取る。2つめは失敗したときに呼ばれる関数で、エラー番号の1は「許可されなかった」、2は「位置を特定できなかった」、3は「時間切れ」を表す。3つめは動作の設定で、本ツールでは、次の値を指定している。
| 設定項目 | 指定値 | 意味 |
|---|---|---|
| enableHighAccuracy | false | 高精度(GPSなど)を要求しない。電力と時間を節約でき、最寄りの都市を選ぶ用途には十分 |
| timeout | 12000 | 12秒(ミリ秒で指定)たっても位置が分からなければ、失敗として扱う |
| maximumAge | 60000 | 60秒以内に取得した古い位置があれば、再計測せずそれを使ってよい |
位置情報には、いくつか注意点がある。1つめは、使える場所の条件である。Geolocation APIは、通信が暗号化されているHTTPSのページなど、セキュアコンテキストと呼ばれる安全な場所でしか使えない。ローカルのファイルとして開いたHTMLについては、ブラウザによって扱いが異なる。本ツールはGeolocation APIが使えなくても都市を手動で選べるようにしてあり、位置情報に頼りきらない作りになっている。スマートフォン実機でローカルのHTMLファイルを開いたときの位置情報の動作は、OSやブラウザに依存するため、本項の検証では確認していない。

2つめは、失敗の種類の多さである。位置情報は、利用者が許可しない、屋内で位置が分からない、電波が届かない、ブラウザが対応していない、といった理由で取れないことがよくある。位置情報が取れたときだけ動くプログラムは、実際にはほとんど使えない。本ツールは、取得に失敗した場合、理由を画面に表示したうえで、都市を手動で選ぶよう案内する。位置が取れなかったときの初期表示は東京にしてある。

3つめは、待ち時間の扱いである。許可を求めるメッセージが出ている間、利用者が何も押さなければ、プログラムはずっと待たされる。仕様上、timeoutの時間には許可を待つ時間が含まれないとされている。そこで本ツールは、timeoutとは別に、15秒たったら位置情報の取得を打ち切って手動選択に切り替える見張りを置いている。この見張りの考え方は「通信を途中で止める」で改めて取り上げる。

4つめは、現在地の扱いである。本ツールは、取得した緯度・経度を、最寄りの地点を決めるためだけに使い、保存も送信もしない。後述のとおり、気象庁へ送る要求の内容は、現在地に関係なく地点ごとの決まったURLだけである。「現在地を調べるために現在地を送る」必要がない作りになっている。ただし、ブラウザやOSが位置を推定する過程で、位置情報サービスに通信する場合がある。これはブラウザやOSの側の設定に従う動作で、ツールの側からは制御できない。
2つめは、失敗の種類の多さである。位置情報は、利用者が許可しない、屋内で位置が分からない、電波が届かない、ブラウザが対応していない、といった理由で取れないことがよくある。位置情報が取れたときだけ動くプログラムは、実際にはほとんど使えない。本ツールは、取得に失敗した場合、理由を画面に表示したうえで、都市を手動で選ぶよう案内する。位置が取れなかったときの初期表示は東京にしてある。
3つめは、待ち時間の扱いである。許可を求めるメッセージが出ている間、利用者が何も押さなければ、プログラムはずっと待たされる。仕様上、timeoutの時間には許可を待つ時間が含まれないとされている。そこで本ツールは、timeoutとは別に、15秒たったら位置情報の取得を打ち切って手動選択に切り替える見張りを置いている。この見張りの考え方は「通信を途中で止める」で改めて取り上げる。
4つめは、現在地の扱いである。本ツールは、取得した緯度・経度を、最寄りの地点を決めるためだけに使い、保存も送信もしない。後述のとおり、気象庁へ送る要求の内容は、現在地に関係なく地点ごとの決まったURLだけである。「現在地を調べるために現在地を送る」必要がない作りになっている。ただし、ブラウザやOSが位置を推定する過程で、位置情報サービスに通信する場合がある。これはブラウザやOSの側の設定に従う動作で、ツールの側からは制御できない。
最寄りの地点を計算する
現在地が分かっても、それが予報の地点とは限らない。そこで、現在地の緯度・経度と、64地点の緯度・経度を比べて、最も近い地点を選ぶ。緯度は赤道から北または南へ何度離れているか、経度は基準になる子午線から東または西へ何度離れているかを表す。たとえば東京は、おおよそ北緯35.7度、東経139.8度である。
AI生成コンテンツ / AI-generated content
距離を求めるとき、学校で習った「縦の差と横の差の2乗を足して平方根を取る」計算(三平方の定理)をそのまま使うと、ずれが出る。地球は丸く、経度1度の長さが緯度によって変わるからである。経度1度の長さは、赤道上で約111kmあるが、北緯35度付近では約91kmに縮み、北極に近づくほど短くなる。緯度1度の長さはほぼ一定(約111km)なので、縦と横を同じ尺度で扱うことはできない。
地球のような丸い面の上で、2点の間の最短距離を求める計算にハーヴァサイン公式(haversine formula)がある。2点を結ぶ「地球の表面に沿った最短の道(大円の弧)」の長さを、緯度・経度から求める式である。式の中身を理解する必要はなく、「地球が丸いことを考慮して距離を求める定番の計算」と捉えておけば十分である。本ツールの実装は次のとおりである。
weeklyWeather.html(2点間の距離を求める関数)
function distance(latitude, longitude, spot) {
const radians = (value) => value * Math.PI / 180;
const a = Math.sin(radians(spot.lat - latitude) / 2) ** 2
+ Math.cos(radians(latitude)) * Math.cos(radians(spot.lat))
* Math.sin(radians(spot.lon - longitude) / 2) ** 2;
return 6371 * 2 * Math.asin(Math.sqrt(Math.min(1, a)));
}
最初の radians は、度(角度)をラジアンという別の単位に直す小さな関数である。三角関数は角度をラジアンで受け取るため、この変換が必要になる。6371は地球の平均半径(約6,371km)で、最後の行で距離の単位をキロメートルに揃えている。Math.min(1, a) は、計算上の微小な誤差で平方根の中身が1をわずかに超えてしまうのを防ぐための安全策である。

この関数を64地点すべてに対して呼び、距離が最も短い地点を選ぶ。64回ほどの計算であり、利用者が待たされるほどの時間はかからない。ただし、次の制約がある。
この関数を64地点すべてに対して呼び、距離が最も短い地点を選ぶ。64回ほどの計算であり、利用者が待たされるほどの時間はかからない。ただし、次の制約がある。
| 項目 | 内容 |
|---|---|
| 距離の種類 | 地球の表面に沿った直線距離。道のりや所要時間ではない |
| 最寄りの意味 | 64地点の中で最も近い地点。現在地を含む予報区域とは限らない。県境付近では隣の県の都市が選ばれることがある |
| 遠すぎる場合 | 最寄りでも300kmより遠いときは、自動選択せず、国内の都市を手動で選ぶよう案内する(海外にいる場合など) |
| 選んだ後 | 画面に「現在地に最も近い対応地点:〇〇(約〇〇km)」と表示し、利用者が結果を確かめられるようにする |
気象庁XMLを取得する
ブラウザのJavaScriptから、インターネット上のデータを取り寄せる標準の方法がfetch(フェッチ)である。fetchにURLを渡すと、そのURLへ要求を送り、返事(レスポンス)を受け取る。通信には時間がかかるため、fetchは結果をすぐには返さず、Promise(プロミス)を返す。「3.6 重複データ検出・並べ替え」で扱ったasync/awaitを使うと、「届くまで待つ」処理を普通の手順書のように書ける。本ツールの取得部分は、次の流れになっている。
- 配信一覧(regular_l.xml)をfetchで取得する
- 一覧から、選んだ地点の予報XMLのURLを探す
- そのURLをfetchで取得する
- 取得した文字列をXMLとして読み解き、画面に表示する
weeklyWeather.html(fetchによる取得・抜粋)
const response = await fetch(url, {
signal: controller.signal, credentials: 'omit', redirect: 'error',
referrerPolicy: 'no-referrer', cache: refresh ? 'reload' : 'default',
});
if (!response.ok) {
throw new Error(`気象庁XMLの取得に失敗しました(HTTP ${response.status})。`);
}
const xml = parseXml(await response.text());
AI生成コンテンツ / AI-generated content
fetchで最初に確認するのは、HTTPステータスである。Webサーバーは返事に3桁の番号を付け、200番台なら成功、404なら「そのURLにファイルがない」、500番台なら「サーバー側の不具合」を表す。response.ok は、この番号が成功を表す200番台であれば true になる項目である。失敗の場合でも、返ってきた内容をそのままXMLとして読もうとすると、エラーの文面を予報として扱う誤りになりかねない。そのため、本ツールは成功を確かめてから先へ進み、失敗なら「HTTP 404」のようにステータスを画面に出して止まる。

fetchの設定(第2引数)には、通信の安全を高める項目を並べている。
fetchの設定(第2引数)には、通信の安全を高める項目を並べている。
| 項目 | 指定値 | 意味 |
|---|---|---|
| credentials | 'omit' | Cookieなどの認証情報を送らない。気象庁のXMLの取得に、利用者の情報は不要 |
| redirect | 'error' | 別のURLへの転送(リダイレクト)が起きたら、追わずにエラーにする。意図しない場所へ誘導されるのを防ぐ |
| referrerPolicy | 'no-referrer' | どのページから要求したかという情報(リファラー)を送らない |
| cache | 'reload' または 'default' | 「最新の予報を取得」ボタンのときは、ブラウザの保存分を使わず取り直す。通常はブラウザの標準の扱いに任せる |
| signal | controller.signal | 通信を途中で止めるための合図(次項で説明する) |
通信量への配慮も要る。配信一覧は約4.6MBと大きく、地点を切り替えるたびに毎回取り寄せるのは無駄である。そこで本ツールは、取得したXMLを1時間、プログラムの中(メモリー)に記憶して使い回す。同じ一覧を要求している最中にもう1度要求が来た場合は、2回めを送らず、1回めの結果を共有する。なお、気象庁のサーバーは、配信一覧に cache-control: max-age=60(60秒)を付けて返している。本ツールが取り直すのは、1時間たったときと、利用者が「最新の予報を取得」を押したときだけである。自動で定期的に取得し直す機能(自動巡回)や、失敗したときの自動再試行は入れていない。気象庁のサーバーに、不要な負担をかけないためである。

もう1つ、ブラウザには同一生成元ポリシー(Same-Origin Policy)という安全の決まりがある。あるページのJavaScriptが、別のサイト(生成元が異なるサイト)から取り寄せた返事を読むことを、ブラウザは原則として禁止する。悪意のあるページが、利用者のログイン中の別サイトの内容を勝手に読み取るのを防ぐためである。ただし、相手のサーバーが「どのサイトから読んでもよい」と返事に明記していれば、読むことが許される。この許可の仕組みをCORS(コルス)と呼ぶ。著者が2026年(令和8年)10月24日に確かめたところ、気象庁のXMLサーバーは、配信一覧にも個別の予報XMLにも access-control-allow-origin: * を付けて返しており、どのページからでも読める状態であった。本ツールが、サーバーを介さずブラウザから直接XMLを読めるのは、この許可があるからである。同じfetchの書き方でも、許可していないサイトに対しては、読み取りがブラウザによって拒否される。
もう1つ、ブラウザには同一生成元ポリシー(Same-Origin Policy)という安全の決まりがある。あるページのJavaScriptが、別のサイト(生成元が異なるサイト)から取り寄せた返事を読むことを、ブラウザは原則として禁止する。悪意のあるページが、利用者のログイン中の別サイトの内容を勝手に読み取るのを防ぐためである。ただし、相手のサーバーが「どのサイトから読んでもよい」と返事に明記していれば、読むことが許される。この許可の仕組みをCORS(コルス)と呼ぶ。著者が2026年(令和8年)10月24日に確かめたところ、気象庁のXMLサーバーは、配信一覧にも個別の予報XMLにも access-control-allow-origin: * を付けて返しており、どのページからでも読める状態であった。本ツールが、サーバーを介さずブラウザから直接XMLを読めるのは、この許可があるからである。同じfetchの書き方でも、許可していないサイトに対しては、読み取りがブラウザによって拒否される。
通信を途中で止める
AI生成コンテンツ / AI-generated content
通信は、相手の都合や回線の状態で、いつまでも終わらないことがある。画面に「取得しています…」と出たまま何も起きなければ、利用者は不安になる。仕様書にも「無限ループに陥ったり、システム・エラーが出たときは、画面にエラー情報を表示して終了すること」と書いた。そこで本ツールは、通信に時間の上限を設けている。
fetchの通信を途中で止めるには、AbortController(アボート・コントローラー)を使う。AbortControllerを作り、その合図(signal)をfetchに渡しておく。後で abort() を呼ぶと、fetchは通信を中止し、エラー(AbortError)で終わる。時間の上限は、setTimeout で「20秒後に abort() を呼ぶ」と予約して実現する。
weeklyWeather.html(通信の時間制限・抜粋)
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 20000);
try {
const response = await fetch(url, { signal: controller.signal });
// (中略)
} catch (error) {
if (error.name === 'AbortError') {
throw new Error('通信が20秒以内に完了しませんでした。処理を終了しました。');
}
if (error instanceof TypeError) {
throw new Error('気象庁XMLに接続できません。回線・ブラウザの通信制限を確認してください。');
}
throw error;
} finally {
clearTimeout(timer);
}
try…catch は、「3.6」の「async/awaitで『待つ』処理を書く」で触れた、エラーを受け止める書き方である。ここでは、エラーの種類によって利用者へ伝える文面を変えている。AbortErrorは「20秒たったので止めた」、TypeErrorは「そもそも接続できなかった」(回線が切れている、ブラウザが通信を拒否した、など)を表す。それ以外のエラーは、そのまま上へ渡す。finally の中の clearTimeout は、通信が20秒より早く終わったときに、予約しておいた「20秒後の中止」を取り消す処理である。取り消さないと、成功した後に、不要な中止命令が残ってしまう。

本ツールには、待ち時間の見張りが複数ある。それぞれの役割を表に整理する。
本ツールには、待ち時間の見張りが複数ある。それぞれの役割を表に整理する。
| 対象 | 上限 | 時間切れのときの動作 |
|---|---|---|
| 位置情報(ブラウザの設定) | 12秒 | 失敗の関数が呼ばれ、理由を表示して手動選択を促す |
| 位置情報(許可の待ち時間も含む見張り) | 15秒 | 取得を打ち切り、都市を手動で選ぶよう案内する |
| 気象庁XMLの通信(1回につき) | 20秒 | 通信を中止し、エラー表示。「最新の予報を取得」ボタンで再実行できる |
想定していない不具合(プログラムの書き間違いなど)への備えもある。本ツールは、ブラウザ全体のエラーを受け取る window.addEventListener('error') と、受け止め損ねた非同期処理のエラーを受け取る unhandledrejection の2つを監視している。どちらかが起きると、すべてのボタンとプルダウンを使えなくして、「処理を停止しました。ページを開き直してください」と画面に表示する。「3.5 ToDoリスト」で扱った error イベントの考え方を、さらに一歩進めて、「おかしくなったまま動き続けて誤った予報を表示する」ことを避ける設計である。
XMLを読み解く
fetchで受け取ったXMLは、ただの長い文字列である。そこから「福岡県の10月26日の天気」といった値を取り出すには、文字列をプログラムが扱える形に直さなければならない。ブラウザには、XMLの文字列を、タグの入れ子をそのまま再現した木のような構造(DOM)に変換するDOMParser(ドム・パーサー)という道具がある。変換した後は、「Weatherというタグの部分を全部探す」といった検索ができる。

実際の予報XMLが、どのような形をしているかを見てみよう。次に示すのは、著者が2026年(令和8年)10月24日に取得した福岡県の週間予報XMLから、主な値だけを残して簡略化したものである。実際のファイルは約16KBあり、途中に Kind、Property といった階層や、気温の予測範囲など、ここに書いていない項目が多数ある。
実際の予報XMLが、どのような形をしているかを見てみよう。次に示すのは、著者が2026年(令和8年)10月24日に取得した福岡県の週間予報XMLから、主な値だけを残して簡略化したものである。実際のファイルは約16KBあり、途中に Kind、Property といった階層や、気温の予測範囲など、ここに書いていない項目が多数ある。
20261024014928_0_VPFW50_400000.xml(福岡県の府県週間天気予報・簡略化)
<Report xmlns="http://xml.kishou.go.jp/jmaxml1/"> <Control> <Status>通常</Status> <PublishingOffice>福岡管区気象台</PublishingOffice> </Control> <Head> <ReportDateTime>2026-10-24T11:00:00+09:00</ReportDateTime> <InfoType>発表</InfoType> </Head> <Body> <MeteorologicalInfos type="区域予報"> <TimeSeriesInfo> <TimeDefines> <TimeDefine timeId="1"><DateTime>2026-10-25T00:00:00+09:00</DateTime></TimeDefine> <TimeDefine timeId="2"><DateTime>2026-10-26T00:00:00+09:00</DateTime></TimeDefine> </TimeDefines> <Item> <jmx_eb:Weather type="基本天気" refID="2">雨</jmx_eb:Weather> <jmx_eb:ProbabilityOfPrecipitation type="日降水確率" unit="%" refID="2">90</jmx_eb:ProbabilityOfPrecipitation> <Area><Name>福岡県</Name><Code>400000</Code></Area> </Item> </TimeSeriesInfo> </MeteorologicalInfos> <MeteorologicalInfos type="地点予報"> <TimeSeriesInfo> <Item> <jmx_eb:Temperature type="最低気温" unit="度" refID="1" condition="値なし"/> <jmx_eb:Temperature type="最低気温" unit="度" refID="2">21</jmx_eb:Temperature> <jmx_eb:Temperature type="最高気温" unit="度" refID="2">26</jmx_eb:Temperature> <Station><Name>福岡</Name><Code>82182</Code></Station> </Item> </TimeSeriesInfo> </MeteorologicalInfos> </Body> </Report>
XMLの構造を読む手がかりを表にまとめる。
| 要素 | 役割 | 本ツールでの使い方 |
|---|---|---|
| Status | 電文の状態(通常、訓練、試験など) | 「通常」以外のときは、誤表示を避けるため表示を止める |
| InfoType | 発表の種別(発表、訂正、取消など) | 「取消」のときは、取り消された予報として表示を止める |
| MeteorologicalInfos の type | 予報の種類。区域予報は天気・降水確率・信頼度、地点予報は気温 | 区域予報と地点予報の2種類から値を集める |
| TimeDefine の timeId | 時刻の番号と、その日の日付 | 値の側の refID と突き合わせて日付を決める |
| Area の Code | 予報区域コード(福岡県は400000) | 天気・降水確率・信頼度は、この区域コードで探す |
| Station の Code | 観測地点コード(福岡は82182) | 最高・最低気温は、この地点コードで探す |
| condition="値なし" | その時刻の値が発表されていない印 | 空欄として扱い、画面には「—」と表示する |
この構造には、読み取りの注意点がいくつかある。1つめは、日付の突き合わせである。予報の値は、日付そのものではなく、番号(refID)を付けて並んでいる。日付は別の場所(TimeDefine)に番号と対応させて書かれている。そのため、プログラムは最初に「番号と日付の対応表」を作り、各値の番号を日付に直してから、日付ごとにまとめる。

2つめは、天気と気温で、取り出す場所が違う点である。天気・降水確率・信頼度は「予報区域」を単位にしているのに対し、気温は「観測地点」を単位にしている。たとえば福岡県では、区域コードは400000、観測地点(福岡)のコードは82182である。1つの地点を表示するために、この2種類のコードの両方が要る。本ツールの地点表にコードを2つ持たせているのは、そのためである。どちらか一方でも見つからなければ、推測で補わず、「地点対応表と配信XMLが一致しません」と表示して処理を止める。誤った予報を表示するよりも、表示しないことを選ぶ設計である。

3つめは、発表値のない日である。上の例の10月25日の最低気温は「値なし」になっている。実際、本項の冒頭の画面でも、先頭の日の気温が「— / —」と表示されている。発表の時刻によっては、最初の日の値がそろっていないことがある。本ツールは、短期予報(府県天気予報)を組み合わせて穴を埋める処理は入れず、発表されていない値は「—」と表示する。「推測で補わない」という方針の表れである。
2つめは、天気と気温で、取り出す場所が違う点である。天気・降水確率・信頼度は「予報区域」を単位にしているのに対し、気温は「観測地点」を単位にしている。たとえば福岡県では、区域コードは400000、観測地点(福岡)のコードは82182である。1つの地点を表示するために、この2種類のコードの両方が要る。本ツールの地点表にコードを2つ持たせているのは、そのためである。どちらか一方でも見つからなければ、推測で補わず、「地点対応表と配信XMLが一致しません」と表示して処理を止める。誤った予報を表示するよりも、表示しないことを選ぶ設計である。
3つめは、発表値のない日である。上の例の10月25日の最低気温は「値なし」になっている。実際、本項の冒頭の画面でも、先頭の日の気温が「— / —」と表示されている。発表の時刻によっては、最初の日の値がそろっていないことがある。本ツールは、短期予報(府県天気予報)を組み合わせて穴を埋める処理は入れず、発表されていない値は「—」と表示する。「推測で補わない」という方針の表れである。
weeklyWeather.html(XMLを読み込む部分・抜粋)
const nodes = (root, name) => Array.from(root.getElementsByTagNameNS('*', name));
function parseXml(text) {
const xml = new DOMParser().parseFromString(text, 'application/xml');
if (first(xml, 'parsererror')) throw new Error('XMLの形式が正しくありません。');
return xml;
}
parseFromString の第2引数に 'application/xml' を指定すると、文字列がXMLとして解析される。XMLの形式が壊れているときは、ブラウザが parsererror というタグのエラー表示を結果に混ぜて返す。本ツールはこれを探し、見つかれば処理を止める。通信が途中で切れて、XMLが半分しか届かなかった場合などに、半端な内容を予報として表示してしまうのを防ぐ。

タグを探す部分には、getElementsByTagNameNS という少し長い名前の命令を使っている。気象庁XMLのタグには、上の例のように、名前空間(ネームスペース)という「どの用語集に属するタグか」を示す印が付いている。冒頭の xmlns=… という宣言がそれで、Weather のように jmx_eb: という接頭辞の付いたタグは、別の名前空間に属している。普通の getElementsByTagName で探すと、この接頭辞の扱いが面倒になる。そこで、第1引数に '*'(どの名前空間でもよい)を指定する getElementsByTagNameNS で、名前だけを頼りに探している。
タグを探す部分には、getElementsByTagNameNS という少し長い名前の命令を使っている。気象庁XMLのタグには、上の例のように、名前空間(ネームスペース)という「どの用語集に属するタグか」を示す印が付いている。冒頭の xmlns=… という宣言がそれで、Weather のように jmx_eb: という接頭辞の付いたタグは、別の名前空間に属している。普通の getElementsByTagName で探すと、この接頭辞の扱いが面倒になる。そこで、第1引数に '*'(どの名前空間でもよい)を指定する getElementsByTagNameNS で、名前だけを頼りに探している。
古い結果で表示を上書きしない
AI生成コンテンツ / AI-generated content
通信にかかる時間は、毎回同じではない。ここに、見落としやすい問題がある。利用者が「東京」を選び、予報が届く前に「大阪」へ切り替えたとする。そのとき、先に送った東京の要求の返事が、大阪の返事より後に届くことがある。何も対策をしないと、大阪を選んでいるのに東京の予報が表示される。このように、処理が終わる順番が思い通りにならないことで起きる不具合を、競合状態(レース・コンディション)と呼ぶ。
本ツールの対策は、要求ごとに連番(requestId)を付けることである。予報を取りにいくたびに番号を1つ増やし、その要求に自分の番号を持たせる。返事が届いたら、「自分の番号が、今の最新の番号と同じか」を確かめ、違えば古い要求の返事なので、何も表示せずに捨てる。
weeklyWeather.html(古い結果を捨てる処理・抜粋)
let requestId = 0;
async function showForecast(refresh = false) { const id = ++requestId; // この要求の番号 // (中略)取得中は、旧都市の予報を消しておく try { const result = readForecast(xml, spot); if (id !== requestId || stopped) return; // 古い要求なら、表示せずに捨てる render(result, spot, url); } catch (error) { if (id !== requestId || stopped) return; status(error.message, true); } }
++requestId は、requestIdに1を足して、その新しい値をこの要求の番号にする書き方である。東京の要求が番号1、大阪の要求が番号2とすると、東京の返事が遅れて届いたとき、requestIdはすでに2になっているため、番号1の返事は捨てられる。エラーのときも同じ確認をしている。古い要求の失敗を、新しい要求の画面に表示しないためである。

似た考え方は、ほかにも2か所に使われている。1つは、取得中に旧都市の予報を画面から消しておく処理である。取得に時間がかかったり失敗したりしたとき、大阪を選んだ画面に東京の予報が残っていると、利用者が誤って読み取るおそれがある。もう1つは、位置情報と手動選択の競合である。現在地の取得中に利用者が都市を手動で選んだ場合は、後から届いた現在地の結果ではなく、手動の選択を優先する。画面には「手動で選んだ都市を優先しました」と表示し、現在地を使いたければ「現在地から選ぶ」ボタンを押すよう案内する。利用者が最後に自分で行った操作を、後から届いた自動の結果で上書きしない、という考え方である。
似た考え方は、ほかにも2か所に使われている。1つは、取得中に旧都市の予報を画面から消しておく処理である。取得に時間がかかったり失敗したりしたとき、大阪を選んだ画面に東京の予報が残っていると、利用者が誤って読み取るおそれがある。もう1つは、位置情報と手動選択の競合である。現在地の取得中に利用者が都市を手動で選んだ場合は、後から届いた現在地の結果ではなく、手動の選択を優先する。画面には「手動で選んだ都市を優先しました」と表示し、現在地を使いたければ「現在地から選ぶ」ボタンを押すよう案内する。利用者が最後に自分で行った操作を、後から届いた自動の結果で上書きしない、という考え方である。
通信先を気象庁だけに絞る
AI生成コンテンツ / AI-generated content
「3.9 QRコード生成・読取ツール」では、Content-Security-Policy(CSP)の connect-src 'none' で、ページからの通信をすべて禁止した。今回のツールは気象庁と通信する必要があるため、「すべて禁止」にはできない。そこで、通信を許す相手を気象庁のXMLの置き場所だけに絞る。通信を禁止するのではなく、許可する相手を限る方式で、許可リスト(アローリスト)と呼ばれる考え方である。
weeklyWeather.html(CSPの宣言)
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src https://www.data.jma.go.jp/developer/xml/; img-src data:; base-uri 'none'; form-action 'none'">
3.9との違いは connect-src の指定である。3.9では 'none'(通信の全面禁止)だったが、今回は https://www.data.jma.go.jp/developer/xml/ と書いてある。これは「この場所の下にあるURLへの通信だけを許す」という意味で、気象庁の別のページや、他のサイトへの通信は、ブラウザが拒否する。さらに base-uri 'none' と form-action 'none' で、ページの基準URLの書き換えと、フォームによるデータ送信も禁止している。

ブラウザの見張りだけでなく、プログラム自身も、取得先を確かめている。配信一覧の中に書かれているURLは、外から届いたデータの一部であり、プログラムの書き手が管理しているものではないからである。万一、一覧に想定外のURLが紛れ込んだとしても、それを無条件にfetchしないようにしている。
ブラウザの見張りだけでなく、プログラム自身も、取得先を確かめている。配信一覧の中に書かれているURLは、外から届いたデータの一部であり、プログラムの書き手が管理しているものではないからである。万一、一覧に想定外のURLが紛れ込んだとしても、それを無条件にfetchしないようにしている。
weeklyWeather.html(取得先のURLを確かめる関数)
function allowedUrl(value) {
const url = new URL(value);
if (url.origin !== 'https://www.data.jma.go.jp'
|| !/^\/developer\/xml\/(feed|data)\/[A-Za-z0-9_.-]+\.xml$/.test(url.pathname)
|| url.search || url.hash || url.username || url.password) {
throw new Error('許可されていないXML取得先です。');
}
return url.href;
}
この関数は、取得先のURLが、次のすべてを満たす場合にだけ通す。満たさなければ、取得せずにエラーにする。
| 確認する部分 | 許可する内容 |
|---|---|
| origin(通信先のサイト) | https://www.data.jma.go.jp だけ(暗号化されていない http や他のドメインは不可) |
| pathname(サイト内の場所) | /developer/xml/feed/ または /developer/xml/data/ の下にある、英数字と記号(. _ -)だけのXMLファイル名 |
| search・hash(?以降、#以降) | 付いていないこと。余計なパラメータで別のデータを呼ばれるのを防ぐ |
| username・password | URLに埋め込まれていないこと |
このように、通信先の安全は、複数の層で守っている。
| 層 | 守っているもの | 破られたときに働くもの |
|---|---|---|
| 1. CSPの connect-src | ブラウザが、気象庁以外への通信を拒否する | プログラムに誤りがあっても通信先を限る |
| 2. allowedUrl 関数 | プログラムが、取得前にURLの形を確かめる | 配信一覧に想定外のURLが混ざっても取得しない |
| 3. fetch の設定 | 認証情報とリンク元を送らず、転送を追わない | 通信先から余計な情報を渡さない・受け取らない |
| 4. 表示のしかた | textContentで画面に出し、HTMLとして解釈させない | XMLの値に変な文字が混ざっても画面を壊さない |
どの層も、単独では万全ではない。複数を重ねることで、1つが破られても被害が広がらないようにしている。「3.7 ハーネスエンジニアリング」で述べた、結果を確かめる仕組みを用意する考え方に通じる。外部のデータを取り込むプログラムでは、外から来るものを信用しない、という姿勢がとくに重要になる。
週間予報カードを描く
取り出した値は、7日分のカードとして画面に並べる。カード1枚には、日付と曜日、天気を表す記号、天気の文字、最高・最低気温、降水確率、信頼度を載せる。画面の作り方は、これまでの項目で扱ってきた内容が中心なので、本項で新しく出てくる要素だけを取り上げる。
予報カードの部分(東京、2026年10月24日11時発表)。先頭の10月25日は気温が「—」
天気予報ツールのプログラム仕様書
以上を踏まえて、天気予報ツール「weeklyWeather.html」の開発開始時にCodexへ渡したプロンプトを示す。実現したい動作(現在地または選択した都市の週間予報の表示)、通信の範囲(気象庁防災情報XMLのみ)、テストの観点は書いてあるが、Geolocation APIの使い方、距離の計算式、fetchやAbortControllerの使い方、XMLの読み方といった具体的な実装方法までは指定していない。これらは、Codexが仕様と参考にするPHPプログラムを読んで選んだ実装である。

開発の途中で確定した事項は、実装後の仕様書(weeklyWeather.md)に追記されている。たとえば、短期予報による補完をせず発表のない値は「—」と表示すること、最寄り地点が300kmより遠いときは自動選択しないこと、位置取得中に手動で選んだ都市を優先すること、位置情報の待ち時間を15秒、通信の待ち時間を1リクエスト20秒にすること、といった判断である。仕様書に書ききれなかった細部の判断を、実装した側が言葉で残しておく進め方は、「3.8 簡易画像編集ツール」や「3.9 QRコード生成・読取ツール」でも触れたとおりである。
開発の途中で確定した事項は、実装後の仕様書(weeklyWeather.md)に追記されている。たとえば、短期予報による補完をせず発表のない値は「—」と表示すること、最寄り地点が300kmより遠いときは自動選択しないこと、位置取得中に手動で選んだ都市を優先すること、位置情報の待ち時間を15秒、通信の待ち時間を1リクエスト20秒にすること、といった判断である。仕様書に書ききれなかった細部の判断を、実装した側が言葉で残しておく進め方は、「3.8 簡易画像編集ツール」や「3.9 QRコード生成・読取ツール」でも触れたとおりである。
開発開始時のプロンプト(天気予報ツール)
# 天気予報ツール
# 目標 - 現在地の週間天気予報を表示する。
# ツール名称 天気予報ツール
# プログラム・ファイル名 weeklyWeather.html
# プロジェクト・フォルダ作成 - プログラム・ファイル名の拡張子を除いた主ファイル名と同じ名前のサブフォルダを作成し、以降の作業はサブフォルダで行う。 - すでにサブフォルダがあれば、そのサブフォルダに移動して以降の作業を進める。
## 画面構成と処理 - プログラム上部にツール名称、バージョン番号、著作権者を記載する。 - 現在、デバイスがいる位置情報を取得し、その地点に近い都市の週間天気予報を表示する。 - プルダウンで、地方、都道府県、都市名を選択し、その都市の週間天気予報を表示する。 - 処理は、`https://www.pahoo.org/e-soul/webtech/php06/php06-72-01.shtm` にあるPHPプログラムを参考にする。気象庁防災情報XMLを参照する。
## 記録 - なし
## 通信 - 気象庁防災情報XMLのみと通信する。
## 例外・エラー処理 - 無限ループに陥ったり、システム・エラーが出たときは、画面にエラー情報を表示して終了すること。
# テスト観点・合格条件 - Codexは、ランダムに都市名を5つ選択し、週間天気予報が画面に表示されることと、その内容が気象庁発表の予報と合致することを検証する。 - 前提条件、制約条件が守られていること。
# 前提条件 - 仕様変更があった場合は、本書を更新する。 - バージョン番号、著作権者、MIT Licenseであることを画面に表示する。 - 仕様で分からないことがあり、その違いが実装結果へ大きく影響する場合はユーザーに質問する。 - 安全かつ合理的に判断できる軽微な事項は、判断内容を明記して作業を進める。 - HTML、CSS、JavaScriptを1つのHTMLファイルに記述する。 - クライアントPCのブラウザで動作し、スマートフォンでも利用できること。 - HTTPサーバーやNode.jsなどのサーバー技術は使用せず、ブラウザの機能だけで完結すること。 - コーディングは「Airbnb JavaScript Style Guide」に可能な限り準拠すること。 - プログラムファイルのコメントに、名称、バージョン、目的、動作環境、著作権表示および使用条件、インストール方法、お問い合わせを記載すること。
# 制約条件 - 気象庁防災情報XML以外とのデータ送受信は行わないこと。 - 外部ライブラリを使用する場合は、下記のサイトに限定すること https://cdn.jsdelivr.net/ https://cdnjs.cloudflare.com/ https://ajax.googleapis.com/ https://code.jquery.com/ https://ajax.aspnetcdn.com/ - プログラムがMIT Licenseおよび第三者の権利に違反していないこと。 - ユーザーの許可なくプロジェクトフォルダ外のファイルを変更しないこと。 - ユーザーの許可なく既存ファイルを削除しないこと。 - Gitの履歴を破壊する操作を行わないこと。
# 合格判定 - すべての実装とテストが完了したら、テスト結果を一覧で表示する。 - 合格項目、不合格項目、未確認項目を明確に区別する。 - 不合格項目がある場合は原因と修正方針を表示する。 - 未確認項目がある場合は未確認の理由とユーザーによる確認方法を表示する。 - テスト結果を表示した後、合格としてよいかユーザーに質問する。 - ユーザーが合格と回答するまでは、Gitへの最終コミットと配布用ZIPファイルの作成を行わない。 - ユーザーが不合格と回答した場合は、指摘内容を修正して再テストする。
# 簡易取扱説明書の作成 - HTMLファイルと同じ場所に、簡易取扱説明書「README.txt」を作成する。 - 説明書には「プログラムの名称」「バージョン」「目的」「動作環境」「著作権表示および使用条件」「インストール方法」「使い方」「操作方法」「成績の保存」「既知の制限」「変更履歴」「お問い合わせ」を含める。 - インストール方法には、ZIPファイルを展開し、本ツールをブラウザで直接開く手順を記載する。 - マウス、キーボード、画面タッチの操作方法を記載する。
# 著作権表示および使用条件 このプログラムは OpenAI社の Codex によって作成し、作者が動作を確認しました。 このプログラムは外部とのデータ通信を行いません。
本アプリケーションはMIT Licenseです。 商用を含む無償利用が可能です。自由に改造できます。 再配布の際は、下記の著作権表記、URLおよび本使用条件を必ず明記してください。
Copyright by (c)studio pahoo https://www.pahoo.org/
MITライセンスについては、下記のリンク先を参考にしてください。 http://ja.wikipedia.org/wiki/MIT_License http://www.opensource.org/licenses/mit-license.php
なお、本アプリケーションの利用または改造によって生じた得失については一切関知いたしません。また、二次利用先の組織・企業・団体の目的・内容・活動については一切関知いたしません。
# お問い合わせ ぱふぅ家のホームページ https://www.pahoo.org/
- サイト案内 - お問い合わせ
# リソース管理 - 作業開始前に、今回の作業が「新規作成(評価用)」「新規作成(配布用)」「メジャーバージョンアップ」「マイナーバージョンアップ」「不具合修正」のどれに該当するかユーザーに質問する。 - 新規作成(評価用)は0.1.0、新規作成(配布用)は1.0.0とする。メジャー、マイナー、不具合修正は既存バージョンを確認して適切に更新する。 - 既存バージョンを確認できない場合は推測せずユーザーに質問する。 - 決定したバージョン番号をツール、README.txt、本書、配布用ZIPファイル名へ反映する。 - ユーザーがテスト結果を合格と判定した後、プログラム、README.txt、本書、および必要なカード画像をGitへコミットする。 - Gitリポジトリが存在しない場合やコミットできない場合は、勝手に新規リポジトリを作成せず、理由を報告して指示を求める。 - コミットメッセージには、プログラム名、バージョン番号、変更区分が分かる内容を使用する。
# 配布ファイルの作成 - ユーザーがテスト結果を合格と判定した後、ツール、README.txt、本書を1つのZIPファイルに圧縮する。 - ZIPファイル名は「プログラム・ファイル名(拡張子を除く)_バージョン番号.zip」とする。 - ZIPファイル内に一時ファイル、テスト用ファイル、Git管理ファイル、デバッグ専用ファイルを含めない。 - 完了後、作成したZIPファイルの絶対パスをユーザーに伝える。
できあがったツールの配布ファイルは、program/weeklyWeather_1.0.0.zip で、中身は weeklyWeather.html、!最初に読んでください.txt、weeklyWeather.md である。バージョンは1.0.0である。気象庁のXMLは日々更新されるため、動作の検証では、ランダムに選んだ5つの都市について、表示した予報が気象庁の発表と合致するかを確かめる条件にした。なお、このツールが表示するのは、気象庁が配信するXMLを表示用に整えたものであり、予報の発表時刻と対象の期間を確認して利用する必要がある。
参考サイト
- PHPで天気予報を求める:ぱふぅ家のホームページ
- 気象庁防災情報XML 配信一覧(長期・定時):気象庁
- 気象庁ホームページを通じて公開するXML電文一覧(PDF):気象庁
- Geolocation API:MDN Web Docs
- Geolocation: getCurrentPosition() メソッド:MDN Web Docs
- セキュアコンテキスト:MDN Web Docs
- Fetch API:MDN Web Docs
- AbortController:MDN Web Docs
- DOMParser:MDN Web Docs
- Document: getElementsByTagNameNS() メソッド:MDN Web Docs
- オリジン間リソース共有 (CORS):MDN Web Docs
- 同一オリジンポリシー:MDN Web Docs
- Content Security Policy (CSP):MDN Web Docs
- Intl.DateTimeFormat:MDN Web Docs
- [https://ja.wikipedia.org/wiki/大円距離:title=大円距離]:ウィキペディア
- Haversine formula:Wikipedia
- Airbnb JavaScript Style Guide:Airbnb
(この項おわり)
