七転び八起きブログ

Atomを選ぶ人とRSSを選ぶ人の差

2005年06月29日   :: XML

O'Reilly Radar > It turns out RSS and Atom really are differentは、O'Reilly Radarにおいて、RSSフィードを読んでいる人とAtomを読んでいる人の動きの差、という記事です。

結果を見ると、RSSで読んでいる人は「Google MapとYahoo! Traffic Back Online」とか「AppleとIntelのウワサについての面白い対談」のような大きなトピックを扱った話題を読むのに対し、Atom利用者は
「Ruby on Rails, and the Rails Beta Book」のような専門的な話題を読む、ということになっています。

その結果については、英語圏でのRSS購読サービスの挙動やらシェアやらが分かりませんので何とも言えないのですが(bloglineでAutoDiscoveryされるのが、Atomだったり)、コメントを見ていて気になったのは、例えばMatthew Gifford氏の2005 08:32 AMの発言の

"RSS1とAtomのユーザとRSS2のユーザの層が違うのは、別に驚くようなことじゃないと思う。それを調べようとすることは有意義なことなのに、子供じみた政治的言い争いになってしまっているのは残念"

とかでしょうか。RSSユーザとAtomユーザの対立が、"Politics"だということです。RDFか否かの2種類の差は、ただフィードを読んでいるだけでは差を全然感じないのですが、どうも開発側では色々と有る様子(あまり差が無いから政治的なものになっているのかもしれませんが)。

[参考リンク]
1)Atom - RSS改訂の試み

XMLHTTPRequestを使う際に気をつけておきたいこと

2005年03月11日   :: XML

logo.gifBaekdal.comは、スカンジナビアでインターネットコーディネータとして働くThomas Baekdal氏のブログ。世界をよりよくする為に情報アーキテクチャなどを研究中とのことです。
 #氏のプロフィールBiography | Baekdal.com
 
そのBaekdal.comから、最近にわかに注目を集めているAjax(Asynchronous JavaScript and XML)を使う際の注意点についての記事がありました。入門者としても示唆される部分が非常にありました。

記事はこちらの「XMLHttpRequest Usability Guidelines」から。XMLHTTPRequrestを使う際に気をつけておきたいこと、です。

■ページのリロードはご法度

まず一つ目。「Do not load entire pages」の項です。
XMLHttpRequestは、ページの一部分だけ変更することがウリです。ですので、これはユーザ側も気をつけることだと思いますが、決してページ全体のリロードをしないことが大事です。開発する立場からすれば、リロードを誘発するようなインターフェイスを用意すべきではない、と言う感じでしょうか。

フレームの欠点と同様に、URLも変わらず中身だけ変わっていきますので、ブックマークが出来なかったり、また、リロードではなくブラウザの「戻る」「進む」ボタンが思ったように使えません。

提供する機能が、例えば、郵便番号のリアルタイムインクリメントサーチ等なら、元々ユーザに「戻る」とか「検索ボックスに文字を入れた状態をブックマークする」といった要望が無いと思いますので、問題は発生しづらいでしょう。
しかし、Baekdal.comでもサンプルとしてあがっていますが、例えばGoogle Mapsでは、見たい地図をブックマークしようとしても、URLはずっと同じなので、ブックマークが出来ません。これは不便です。

XMLHttpRequestではなく、通常のサーバサイドモノでしたら、(妙な言い方ですが)画面全体のリロードが許されるので、見ているページをそのままブックマークすることも可能です。
例えばMapionでは、http://www.mapion.co.jp/c/f?el=139/45/20.789&scl=70000&uc=1&grp=all&nl=35/42/16.679の様に、各ページへのアクセス手段を提供することも可能です。

これは仕組みとして仕方ないことなのでしょうが、中々不便ですね。
XMLHttpRequestを使うページで、例えばパラメータをURLと一緒に渡して、前回の状態を復元したりできるんでしょうか?JavaScriptってURLからパラメータ取得出来たりするんでしょうかね。

[05/03/14追記]
location.hashを利用して、状態を復元することができるみたいです。
 #参照:最速インターフェース研究会 :: [Ajax] location.hashを使ったセッション復元
[/追記終わり]

[05/03/15追記]
しかも今度はこちら、「最速インターフェース研究会 :: [Ajax] エントリの動的ロード」凄いですな…上のカテゴリをクリックするとプルダウンメニューが出ます。その中のエントリーにMouseOverすると、記事が動的に変わります。もちろんURLは変わります。うーむ。すごい。
[/追記終わり]

URLの"index.html#top"のシャープより後ろの部分ですね。
逐一その部分を変えることで、擬似的にURLを変えて、擬似的に各状態に特定のURLを割り当てるようです。なるほど。

■WebアプリとWebサイトの違いに気をつける


続いて「Know the difference between a web application and a website」の項

一般的なデスクトップアプリケーションと同様のガイドラインに親和性が高いWebアプリケーションと、WebSiteの派生であるXMLHttpRequestでは、寄り添うガイドラインが違うので、注意すべきとのことです。User Experience的に良くないと言う事です。

どうなんでしょう、両者は元々それほど遠い位置にあるものではないでしょうし、インターフェイス自体も裏で使われている技術云々ではなく、提供される機能に対して適切に選ばれるべきだと思いますので、両者の違いをことさらに考える必要はないんじゃないかな、と思います。

次は「Do not break what the user is focusing on」です。即座に反応できることに酔って、かえって使用者に余分な作業を強いたり、思考を中断させるような選択肢を提示したりして、使用者の行動を邪魔してはいけないと言うことです。baekdal.comでもあげられていますが、インクリメンタルサーチで、一文字入れた瞬間にずらっとリストが出るのが良い例ですね。

検索するということは、ある程度目的が決まっているわけですから、アルファベット順でリストが出ることは全くの邪魔でしかありません('A`)

スピーディーさが損なわれるばかりか、否応が無しに目に入ってくるものに、余計な気を使う羽目に。

しかし、例えばAppleが次のOSで採用する Spotlightの用に、使用者が入力するテキストに関して、ある程度の曖昧さを持って検索するであろう場合などには、非常に有益な技術だと思います。使用者がそれを使う際の目的や事情を良く考えた上で、XMLHttpRequestの持つレスポンス性能の良さを使いましょう、と言う感じですね。

■そのほかの項目

そのほかの項目は、XMLHttpRequestを使えない人のことも考えようなどの小項目です。
と言うわけで、baekdal.comから、AjaxもTPOを考えて使いましょう、という警告でした。

XMLHttpRequest入門【メソッド等の確認とシンプルなコード】

2005年03月08日   :: XML

前回のエントリーXMLHttpRequestの門を軽く叩いてみる::[7korobi8oki.com]にて、XMLHttpRequest家の門に軽くノック、というか遠くから石を投げて、様子を伺ってみたりしました。

前回のサンプルソースは簡単だったので付け焼き刃で何とかなりましたが、こりゃさらなる理解にはまず地固めが必要だと実感。

そこで、前回のエントリーで参考サイトとして上げましたHawk's W3 Laboratory : XML さんのページに参考リンクとして貼られていたサイトを周りつつ、気がついたところなどを抜き出していこうと思います。

■XMLHTTPRequestとは何ぞや

XMLHTTPRequestとは何ぞやと言うところからですが、javascript:xmlhttprequest [JPSPAN]によりますと、こういったことが出来るもののようです。

XMLHttpRequest is a native JavaScript object allowing further HTTP requests to be made from a page which has already loaded.

「すでに読み込んだページからさらにHTTPRequestを発することが出来る、ネイティブのJavaScriptのオブジェクトとのことです。完全にページをリロードすること無しに、一部を変更したり出来るという。

JavaScriptで、ローカルでDOMを通じてフォームの中身をいじったり、背景をリロード無しで変えられますが、これがサーバ間での処理も同様に出来るようになったというイメージでしょうか。どのあたりでXMLが絡んでくるんだろう、これだけだとHTTPクライアントでは、と思いましたが、Hawk's W3 Laboratoryさんによりますと、

極端な言い方をすればXMLに関連するのは responseXML プロパティを参照する時だけであり、それ以外の部分では”単なる”HTTPクライアント・コンポーネントと考えて差し支えありません

とのことです。ひとまず、XMLとしてパースできるHTTPクライアントとしてとららえればいいみたいです。
ちなみに、もともとはこの仕組み、Internet Explorer のActiveX関係のコンポーネントで、後にそのAPIをMozillaなど他のブラウザががサポートしたという経緯のようです。

The original implementation came from Microsoft as an ActiveX object for IE. Mozilla followed suit and implemented XMLHttpRequest with an (almost) identical API. Konqueror (and Safari v1.2, based also on KHTML) also has an XMLHttpRequest implementation and support should be coming in Opera from v7.6x+.

こんな感じでXMLHTTPRequestオブジェクトのあらましが何となくつかめた所で、次の項。続いてチュートリアルのあるサイトへのリンク集があります。

しかし、私はこの辺に全く疎いので、その前にHTTPRequestそのものについてインターネット興隆の立役者「HTTP〜前編」にて確認しました。よろしければ。

■どうやってHTTPリクエストをするのか

これは、XMLHTTPオブジェクトのメソッドを使用して行います。先ほどのUsing the XML HTTP Request objectにあるサンプルコードは以下のようになっています。

xmlhttp.open("GET", "test.txt",true); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4) { alert(xmlhttp.responseText) } } xmlhttp.send(null)

openメソッドを用いて、test.txtに対してGETメソッドを送っています。そして、それをトリガーとして(onreadystatechangeイベントで)関数を呼び出しています。このあたりは前回のエントリーと全く同じですね。HTTPリクエストを送った際に発生するイベントのハンドラがonreadystatechangeでした。そして、"readyState == 4"は、それに対するレスポンスが完全にダウンロードされたら、という意味でした。

さて、頻出するメソッドだけ眺めているのも不透明で気持ちが悪いので、DevGuru XML DOM HttpRequest Objectの、メソッド一覧を見てみました。どんなのがあるのやら。簡単に訳してみます。

1)HttpRequest.abort( )
現在送っているHTTPリクエストを中断する。オブジェクトは"UNINITIALIZED"という状態を返す。続いてopenメソッドが呼ばれないといけない。

使用例:HttpRequest.abort( )

2)getAllResponseHeaders
このメソッドは、指定したHTTPヘッダを文字列として取ってくる。nameとvalueの組み合わせは、CR/LFで分けられている。

使用例;HttpRequest.getAllResponseHeaders( )

3)open
Microsoft.XMLHTTPリクエストを初期化して使えるようにする。同時にURLや認証の情報を付加する。

使用例;HttpRequest.open(Method[GET or POST], URL, Async, User, Password)

4)send
サーバに実際にリクエストを送信する

使用例:HttpRequest.send(varHeader)

5)setRequestHeader
リクエストヘッダーを加える。コロンの無いテキストであるべし。すでにあるヘッダーを指定すると上書きされる。

使用例;HttpRequest.setRequestHeader(bstrHeader, bstrValue)

そして、プロパティー一覧。大体が読み出しオンリーです。レスポンスの内容などが入っていたりします。
どのように取り出すかどうかで使うプロパティーが違います。普通に文字列として取り出したいときはHttpRequest.responseTextですし、XMLとしてパースされた状態で欲しい場合はHttpRequest.responseXMLです。詳しくは原文まで。

同ページの、サンプルコードは、ASPにデータをPOSTしてレスポンスを返す関数。

function PostOrder (xmldoc) { var xmlhttp = new ActiveXObject ("Microsoft.XMLHTTP"); xmlhttp.Open("POST", "http://guruserver/processorder.asp", false); xmlhttp.Send(xmldoc); return xmlhttp.responseXML; }

です。new ActiveXObjectでオブジェクトを生成して、openメソッドで http://guruserver/processorder.aspに対するPOSTリクエストを同期状態で送る準備をし、その旨をサーバに伝えます。そして、sendメソッドでデータを送信。非同期では無いのでonreadystatechangeを使う必要は無く、返ってきたレスポンスを、responseXMLから取得して返り値に。

非同期、同期は、Openの三つ目のブーリアン値で指定します。trueにすると非同期になります。非同期の場合、Sendメソッドが行われた瞬間すぐにリクエストが発され、レスポンスが完全に帰ってくるこない関わらず、スクリプトがどんどん実行されます。falseを指定すると同期になり、レスポンスが完全に帰ってくるまで待機します。

同期だと、サーバが落ちていた時に延々と待つことになってしまうので、非同期にしてonreadystatechangeでレスポンス完了を検地した方が、色々と柔軟に対応できそうです。
 #この辺りは詳しくはDynamic HTML and XML: The XMLHttpRequest Objectがオススメです。
 #iTunesのRSSをリアルタイムに表示するサンプルもにありますね。

こんな感じでレスポンスを取得します。
また、同様のサンプルがいくつかUsing the XML HTTP Request objectにありますので、続いてそちらも。

■サンプルをいくつか

指定したURLのレスポンスヘッダーを表示するものです。

xmlhttp.open("HEAD", "/faq/index.html",true); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4) { alert(xmlhttp.getAllResponseHeaders()) } } xmlhttp.send(null)

/faq/index.htmlに対して、非同期でHEADリクエストをします。
そして、リクエストが行われたらそれをトリガーとして、レスポンスの読み込みが完了次第getAllResponseHeaders()でヘッダーを全て取得し、アラートとして表示します。最後にnullを送るのはお作法でしょうか?('A`)

続いて、指定したURLが存在するかどうかを調べるものがあります。あんまり転載するのも申し訳ないので要点だけ抜き出しますと、返ってきたステータスコードがいくつかで判断します。コードでは"xmlhttp.status==200"だったら、URLは生きているということに。404だったら存在しないということになります。

ひとまず、XMLHTTPRequestの基礎についてでした。基本的なデータの取得などはこれでも何とかなりそうですが、もちっと包括的に理解したいです。また掘り下げたいと思います。

XMLHttpRequestの門を軽く叩いてみる

2005年03月07日   :: XML

XMLHttpRequestとJavaScriptの組み合わせで、今までのWeb Applicationのように画面が逐次読み込まれるのではない、画面変移の無いWebインターフェイスが実現できるとのこと。そしてそれを"Ajax(エイジャクス)"とも呼ぶらしいです。flickrもAjax使ってるとか。
 #参照;Ajax - Async Javascript with XmlHttpRequest: blog.bulknews.net「Ajax - Async Javascript with XmlHttpRequest」

AjaxXMLHttpRequestで検索すると、たくさん色々出てきます。使ってみると何か不安になるほどさくっと処理結果が返ってきてびっくりします。ローカルのアプリケーションと遜色ない感じです。興味津々。

さて、そんなAjaxも私にとっては高い壁なので、入門として、Guide to Using XMLHttpRequest (with Baby Steps) from WebPastiesの、リアルタイムにZipcodeから州名と都市名を返すフォームと言うのを見てみました。

以下はソース読みのメモです。備忘録。
オリジナルのサイトのソースを見ながら出ないと、ソースを上から順番に読んでるのではなく、作っている過程の流れに沿って読んでいるので、分かりにくいかも。

まず、HTTPオブジェクトを生成する関数です。
クロスブラウザの為に色々と分岐が行われています。

function getHTTPObject() {
var xmlhttp;
/*@cc_on

@cc_onとは、 条件付きコンパイルをオンにするということです。
あるメソッドをサポートしているか、などで、その後のスクリプトを分岐させられるのが、条件付きコンパイル。
 #参照;http://homepage3.nifty.com/aya_js/js3/js314.htm

@_win32 @_win16 @_mac
@_alpha @_x86 @_mc680x0 @_PowerPC
@_jscript @_jscript_build @_jscript_version
といった変数が最初から用意されていて、それぞれtrueかNaNを返します。
それぞれの条件付きコンパイル変数については
MicrosoftMSDN"JScript .NET"を参照。

ちなみにコメント内でも効果はあるので、コメント内にこのように書いたらダメ。
条件付きコンパイルは、非対応のブラウザでエラーが出ないように、通常コメント内に書きます。

@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}

今回は@_jscript_version で判別。
バージョンが5以上だったら、Msxml2.XMLHTTPというXMLHTTPのオブジェクトを生成。
出来なかったら、Microsoft.XMLHTTPというオブジェクトを生成。

Using the XML HTTP Request objectによると、ActiveXObject("Msxml2.XMLHTTP") と ActiveXObject("Microsoft.XMLHTTP") は、Internet Explorer用で、IE内のMSXMLのバージョンが古いと後者しか使えないらしいです。


とりあえずここは、XMLHTTPオブジェクトを作れるかどうかのチェックらしいです。
色々なところを覗いてもほぼ同じ書き出しなので、決まり文句かも。

そして、

@else
xmlhttp = false;
@end @*/

バージョンが5より小さいか、先の@if節でのチェックに漏れたら、XMLHTTPオブジェクトは作れないとしてフラグにfalse入れます。

if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = false;
}
}
return xmlhttp;
}

XMLHTTPがfalseで、かつ、XMLHttpRequestオブジェクトが存在する場合は、XMLHttpRequest()コンストラクタでXMLHttpRequestオブジェクトを生成します。
要するにさっきの条件コンパイルは恐らくIEでしか動かないので(JScriptだし)、こちらがMozilla系用。

それもだめなら、falseを返して処理を終了。
そして、HTTPオブジェクトを生成します。

var http = getHTTPObject(); // We create the HTTP Object

ここから、実際にZipCodeから、州名等を呼び出す処理を加えていきます。
州名を返すプログラムは、ここでは getCityState.phpにしています。
パラメータで、ZipCodeを送ると、州名などが帰ってくるようになっています。getCityState.php?param=17534の様に。


これらをするため、まず、先ほどのgetHTTPObject() 関数の前に、handleHttpResponse()関数を書きます。

urlを変数に入れておきます。

var url = "getCityState.php?param=";

handleHttpResponse関数は、プログラムから帰ってきた州名と都市名をフォームに反映させるための関数です。
最初の"http.readyState == 4" は、httpdリクエストが完了した、つまりオブジェクトのダウンロードが完了したら処理をするという意味です。
readStateについては、
MicrosoftMSDN readyStateの項の、

uninitialized オブジェクトはデータでイニシャライズされていない
loading オブジェクトはデータをロード中である。
interactive オブジェクトはデータをロード中であっても、操作可能である。
complete コントロールは完全にロードされた。

という部分で、ここの上から順に1〜4に対応しています。
つまり、完全にダウンロードされたらということです。

サーバからのレスポンスが完全にローカルにダウンロードされたら、コンマをセパレータにしてレスポンスを配列にして、それぞれをフォームに入れます。ここは、このまんまです。

function handleHttpResponse() {
if (http.readyState == 4) {
// Split the comma delimited response into an array
results = http.responseText.split(",");
document.getElementById('city').value = results[0];
document.getElementById('state').value = results[1];
}
}

そして、この関数を呼び出すタイミングを見計らっているリスナーみたいな関数が、updateCityState() です。
こいつを、さきのhandlehttpResponse関数の下に加えます。

function updateCityState() {
var zipValue = document.getElementById("zip").value;
http.open("GET", url + escape(zipValue), true);
http.onreadystatechange = handleHttpResponse;
http.send(null);
}

zipというIDの振られたテキストボックスの中身をzipValueと言う変数に代入し、それを先ほどのphpプログラムに送ります。

そしてここがキモですが、onreadystatechangeというイベントハンドラを使って、先ほどのhandleHttpResponse関数を呼び出します。

onreadystatechangeというイベントハンドラはスクリプトなどでHTTPリクエストを送った際に発生するハンドラの様です。具体的にはXMLHttpRequest.readyStateが変化した場合に発生するらしいです。(参考;道楽日記 - 2005-03-01

詳しくはデベロッパーズコーナー:DOMプログラミング講座や、Hawk's W3 Laboratory : XML : XMLHttpRequestについてが良いと思います。

大本のupdateCityState関数は、onblurで呼ばれますので、
「ZipCode入力してフォーカス外す」
 ↓
「onblurイベント発生」
 ↓
「updateCityState関数を呼び出し、その中でhttpリクエスト」
 ↓
「onreadystatechangeイベント発生」
 ↓
「handleHttpResponse関数呼び出し」
 ↓
「レスポンスのダウンロード完了」
 ↓
「フォームにレスポンスを加工したものを代入」

という流れです。

こんな感じでしょうか。
自分は、http.openといった様な、HTTP オブジェクトについての理解が全く無いので、この辺りもちゃんと頭に入れておかないとまずそうですな…。

しかし、JavaScriptって気がついたらえらい色々出来るものになってるんですね。ウィンドウを動かすとかばっかり載ってる時代のハンドブックしか無いので、ジェネレーションギャップというか、久しぶりにあった従兄弟がムキムキになっていたとか、そういう気持ちです('A`)

XMLHTTPRequestについては
 #Hawk's W3 Laboratory : XML : XMLHttpRequestについて
 #MSXML SDK Overview

で、かなり幸せになれそうです。

mail TOP