P1380314 on Flickr

はじめに

2009年11月21日(土)の午後,ナンダカンダで半年以上ぶりになってしまった,DeLLa.JS「JavaScript第5版」読書会の第12回目を,吹上ホールは第10会議室で行いました.

以下,その内容をざっと,復習を兼ねて.

読書会

P1380315 on Flickr

XMLHttpRequestオブジェクトを使った同期通信

※「XMLHTTPRequest」は以下,「XHR」と略します.

var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send(null);
 
if (xhr.status == 200) {
  alert(xhr.responseText);
}
else {
  alert('error');
}

XMLHttpRequestオブジェクトを使った非同期通信

readystatechangeイベントがカギですね.

var xhr = new XMLHttpRequest();
 
xhr.onreadystatechange = function () {
  if (xhr.readyState == 4) {
    if (xhr.status == 200) {
      alert(xhr.responseText);
    }
}
 
xhr.open('GET', url);
xhr.send(null);

IEでは,attachEvent()/detachEvent()でも可能とのこと.

モダンなブラウザ(?)におけるaddEventListener()/removeEventListener()では対応していない,というような話がありましたが,これを書いている時点で確認してみたところ,どうやらできるっぽいですね.といってもSafari4でしか確認していませんが.

xhr = new XMLHttpRequest()
XMLHttpRequest
xhr.addEventListener('readystatechange', function(){console.log('[1] ' + xhr.readyState + ' ' + xhr.responseText.length);}, false)
undefined
xhr.addEventListener('readystatechange', function(){console.log('[2] ' + xhr.readyState + ' ' + xhr.responseText.length);}, false)
undefined
xhr.open('GET', 'http://blog.iwa-ya.net/')
[1] 1 0
[2] 1 0
undefined
xhr.send(null)
undefined
[1] 2 0
[2] 2 0
[1] 3 218
[2] 3 218
[1] 3 693
[2] 3 693
[1] 3 1094
[2] 3 1094
 
...
 
[1] 3 78073
[2] 3 78073
[1] 3 79429
[2] 3 79429
[1] 3 82721
[2] 3 82721
XHR finished loading: "http://blog.iwa-ya.net/".
[1] 4 82721
[2] 4 82721

readyState 3

Firefoxでは,readyStateが3のままでも,ダウンロードの進行を示すためにreadystatechangeイベントが複数回発生するのに対し,IEでは,readyStateの値が変化したときだけ,同イベントが発生する,という違いがあるようです.

先の実行結果より,Safari(少なくとも4)は,Firefoxと同じような挙動だということがわかります.

POSTメソッドによる通信

HTMLにおける<form>要素のデフォルトのenctype属性がapplication/x-www-form-urlencodedであるように,XHRオブジェクトにも,そのような設定を明示的に行ってやる必要があります.これにはXHR#setRequestHeader()メソッドを呼び出します.

var xhr = new XMLHttpRequest();
 
...
 
xhr.open('POST', url);
xhr.setRequestHeader('Content-TYpe',
                     'application/x-www-form-urlencoded');
xhr.send(params);

レスポンスのヘッダ

XHR#getAllResponseHeaders()

レスポンスにおけるヘッダすべてが,一つの文字列で得られます.ごにょごにょするには,この値を解析する必要があります.

xhr.getAllResponseHeaders()
Date: Mon, 23 Nov 2009 08:41:31 GMT
X-Powered-By: PHP/5.2.11
X-Pingback: http://blog.iwa-ya.net/xmlrpc.php
Connection: Keep-Alive
Transfer-Encoding: Identity
Pragma: no-cache
Last-Modified: Mon, 23 Nov 2009 08:41:32 GMT
Server: Apache/1.3.41 (Unix) mod_ssl/2.8.31 OpenSSL/0.9.8e
Content-Type: text/html; charset=UTF-8
Cache-Control: no-cache, must-revalidate, max-age=0
Keep-Alive: timeout=5, max=20
Expires: Wed, 11 Jan 1984 05:00:00 GMT
typeof xhr.getAllResponseHeaders()
string
XHR#getResponseHeader()
xhr.getResponseHeader('Content-Type')
text/html; charset=UTF-8
xhr.getResponseHeader('content-type')
text/html; charset=UTF-8
xhr.getResponseHeader('content_type')
null
xhr.getResponseHeader('Content-type')
text/html; charset=UTF-8
xhr.getResponseHeader('ContentType')
null

レスポンスのデータ

XHR#overrideMimeType()

レスポンスデータのMIMEタイプを,強制的に指定するためのメソッド...のようです.

...
 
xhr.open(...);
xhr.overrideMimeType('text/xml');
xhr.send(...);
 
...

XHR#abort()

タイムアウト処理.

XHR#open()メソッドの第4,第5引数

次の2つは等価のようです.

open('GET', 'http://example.com/...', true, 'user', 'passwd');
open('GET', 'http://user:passwd@example.com/...', true);

Basic認証でもDigest認証でもOKのようです.

リモートスクリプティング

<iframe>要素を使ったテクニック.

注意事項

ユーザに対するフィードバック

「Ajax通信してますよ」ということをユーザに伝えるべき.

特定の状態へのURL

Ajax通信後に動的に変化した状態を再現できるようなURLを準備すべき.

あー,これは全然心がけてなかったなぁ...

「戻る」ボタン問題

ユーザが混乱しないように.

その他

全体的にIEでのAjax,ActiveXObjectオブジェクトを使った通信に関する話題が多かったですかね.ページをリロードしてもメモリに残ったままとか...この辺は,ActiveXとOSとの関係なんかを理解できれば納得がいくっぽいです.

懇親会

石焼きなチーズオムライス。 on Flickr

吹上の「曼陀羅屋」というお店で,3時間ほど呑んでました.懇親会も勉強会ですね(?)

リンク

読書会における参加者さんのつぶやきのタイムラインと,少ないながら撮影した写真へのリンクを張っておきます.

次回は...?

12月12日(土)ですが,読書会ではありません! 以下のイベントに合流します.

次の読書会は...?

21章「JavaScriptとXML」の部分を,2010年1月中に行う予定です.XMLに詳しい方の参加があるとより楽しくなりそうです.興味のある方,お待ちしています!

おわりに

ここしばらくjQuery依存な書き方しかしてこなかったので,XHRに直接触れるのが非常に新鮮でした >< 今回の範囲を通じて,JavaScriptによるHTTP通信についての理解を1歩くらいは深められたと思っています.

最後に,参加された皆様,そして開催の告知を,他のコミュニティへの転送,Retweetしていただいた方々,ありがとうございました.次回もまたよろしくお願いします!

こちらもあわせてどうぞ

Leave a Reply

直近のつぶやきを読み込みちゅう...