Webプログラミング演習
STEP9
Ajaxを利用したRSSフィード
のタイムライン表示
Ajax
Asynchronous JavaScript + XML
–
クライアントサイド(ブラウザ内)で非同期サーバ通信
と動的ページ生成を組み合わせる技術の総称
–
ウェブアプリケーションの操作性向上
(ページ遷移を伴わない)サーバとの小刻みな通信=必要な
データを必要な時に要求(リクエスト)
非同期通信=サーバの応答(レスポンス)を待つ間も処理を
実行可能
同期通信と非同期通信(1)
リクエスト
レスポンス
ブラウザ
httpサーバ
リクエスト
レスポンス
ブラウザ
httpサーバ
応答待ち
割り込み
同期通信
非同期通信
レスポンス処理は割り込み (コールバック関数)を利用同期通信と非同期通信(2)
リクエスト1
レスポンス1
ブラウザ
httpサーバ
リクエスト1
レスポンス1
ブラウザ
httpサーバ
同期通信
非同期通信
リクエスト2
レスポンス2
リクエスト2
レスポンス2
リクエストの順序とレスポンスの 順序が一致しないことがあるマッシュアップとAjax
マッシュアップ(mashup)
–複数のウェブサービスを組み合わせて,ひとつの複合サービス
を実現すること
(音楽用語から派生)
複数の異なる音源を組み合わせて一つの曲に仕上げる
–組み合わせを前提としたウェブサービスAPIの提供
Google Maps, Amazon商品検索, 楽天トラベルAPI,.他多数
クライアントサイドマッシュアップ
–
ブラウザからJavaScriptやiframeを使ってAPIを利用
–
比較的時間のかかるサービスを利用する場合は,(応答待ちを
しない)Ajaxが適切
XMLHttpRequest
非同期Http通信を実現する機能を提供する,JavaScript組
込みクラス
–主要メソッド
open(HTTPメソッド, URL, 非同期フラグ, 名前, パスワード)
–サーバとの通信方式を設定
HTTPメソッド:”GET”, ”POST”など
URL:HTTPアクセスする先
注:表示ページと同一サーバ上のURLにしかアクセスできない 非同期フラグ:trueなら非同期通信を行う(省略時はtrue)
名前,パスワード:ユーザ認証が必要な場合に指定(省略可)
send(送信データ)
–サーバへのリクエスト送信
送信データ:POSTする場合に送るデータ(不要の時は’’)
XMLHttpRequest(つづき)
–主要プロパティ
onreadystatechange
–通信状態(readyState)の変化時に呼び出される関数
readyState
–通信状態
0 (uninitialized:読み込み開始前の初期状態),
1 (loading:読み込み中),2 (loaded:読み込んだ),
3 (interactive:読み込んだデータを解析中)
4 (complete:読み込んだデータの解析完了)
responseXML
–レスポンスを XML DOM 形式で取得
典型的なAjaxプログラミング
//リクエストの送信
function ajaxRequest(url){
var req = new XMLHttpRequest(); req.open('GET', url, true);
req.onreadystatechange = function(){ if(req.readyState==4){ onResponse(req); } } req.send(''); } //コールバック関数 function onResponse(req){
var myxml = req.responseXML; .... レスポンスXMLの処理 .... } XMLHttpRequestオブジェクトの生成 通信方式の設定 イベント処理関数の設定 通信状態が4(解析完了)になったらコールバック関数を 呼び出す リクエスト送信 XML DOM形式で取得
AjaxでRSSフィードを処理する
RSSフィード
–サイトで公開されている情報の要約を
XML書式
で記述したもの
–この演習ではRDF Site Summary(RSS0.9, RSS1.0)を利用
Ajaxでフィード処理
–興味のあるサイトのRSSフィードをリクエスト
–コールバック関数でフィードの中身を調べて,表示用HTMLタグ
を生成してページに埋め込む
演習
次ページに示すJavaScriptを記述したファイルを作成
–ファイル名は「feed.js」
タイムライン表示用のHTMLファイルを作成し,
JavaScriptを利用
–ファイル名は「timeline.html」
–クライアントサイドマッシュアップなのでページ記述は静的
% cd myblog
feed.js
//RSSフィードの読込指示 function insertFeed(){ ajaxRequest('/~manda/webprg/rss.php'); } //リクエストの送信 function ajaxRequest(url){ var req = requestObj(); req.open('GET', url, true);req.onreadystatechange = function(){ if(req.readyState==4){ onResponse(req); } } req.send(''); } //通信オブジェクトの生成 function requestObj(){
return new XMLHttpRequest(); }
(次ページへつづく)
リクエストするrssフィードのURLを引数として ajaxRequest関数を呼び出す。
//コールバック関数
function onResponse(req){ var rss = req.responseXML; if(rss){
var channel = rss.getElementsByTagName('channel')[0];
var title = channel.getElementsByTagName('title')[0].firstChild.nodeValue; var link = channel.getAttribute('rdf:about');
var items = rss.getElementsByTagName('item'); for(var i = 0; i < items.length; i++){
var ititle = items[i].getElementsByTagName('title')[0].firstChild.nodeValue; var idate = items[i].getElementsByTagName('date')[0].firstChild.nodeValue;
var ibody = items[i].getElementsByTagName('description')[0].firstChild.nodeValue; var ilink = items[i].getAttribute('rdf:about');
showTimeline(title, link, ititle, idate, ibody, ilink); } } } (次ページへつづく)
feed.js(つづき)
サイトタイトル エントリごとの繰り返し エントリタイトル エントリURL サイトURL エントリ日付 エントリ本文 エントリをタイムラインに挿入feed.js(つづき)
//タイムラインへの挿入
function showTimeline(title, link, ititle, idate, ibody, ilink){ var entry = document.createElement('div');
entry.setAttribute('class', 'entry'); entry.innerHTML = '¥ <h3 class="date">'+idate+'</h3>¥ <h4><a href="'+link+'">'+title+'</a><br/>¥ <a href="'+ilink+'">'+ititle+'</a></h4>¥ <div class="body">'+ibody+'</div>¥ ';
var tline = document.getElementById('timeline'); var entries = tline.getElementsByClassName('entry'); for(var i = 0; i < entries.length; i++){
var edate = entries[i].getElementsByClassName('date')[0].firstChild.nodeValue; if(edate < idate) break;
} if(i < entries.length){ tline.insertBefore(entry, entries[i]); }else{ tline.appendChild(entry); } }
(ソースプログラム)
<div class=“entry”>要素を作成 エントリごとのHTML記述(各自の仕様にあわせる) ※ヒアドキュメント風の書き方だが実際は単なる文字列の代入 (JavaScriptにヒアドキュメントは無い.行末の¥は次行への 継続を意味する) タイムライン(id=“timeline”の要素)を取得 タイムラインに挿入済みのエントリ (class=“entry”の要素)に対する繰り返し 日時(class=“date”の要素の内容)を取得 挿入するエントリよりも旧ければ繰り返しを抜ける 途中で抜けた場所に挿入 末尾に追加コールバック関数(onResponse)の
処理内容
各エントリーのHTML記述を作成し,"timeline"と
いうid属性を持つHTML要素の中に日時順に挿
入する
<div class="entry">
<h3>日時</h3>
<h4>
<a href="サイトURL">サイトタイトル</a><br/>
<a href="個別エントリURL">個別エントリタイトル</a>
</h4>
<div class="body">本文</div>
</div>
<div id="timeline">
</div>
挿入
timeline.htmlの作成
head領域内でfeed.jsを読み込む
bodyタグのonload属性でinsertFeed関数を実行
body領域内にタイムライン表示用のHTML要素を置く
<head> ....<script type="text/javascript" src="feed.js">//</script>
.... </head> <body onload="insertFeed()"> .... <div id="timeline/> ....