はじめに
2009年11月21日(土)の午後,ナンダカンダで半年以上ぶりになってしまった,DeLLa.JS「JavaScript第5版」読書会の第12回目を,吹上ホールは第10会議室で行いました.
以下,その内容をざっと,復習を兼ねて.
読書会
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との関係なんかを理解できれば納得がいくっぽいです.
懇親会
吹上の「曼陀羅屋」というお店で,3時間ほど呑んでました.懇親会も勉強会ですね(?)
リンク
読書会における参加者さんのつぶやきのタイムラインと,少ないながら撮影した写真へのリンクを張っておきます.
次回は...?
12月12日(土)ですが,読書会ではありません! 以下のイベントに合流します.
次の読書会は...?
21章「JavaScriptとXML」の部分を,2010年1月中に行う予定です.XMLに詳しい方の参加があるとより楽しくなりそうです.興味のある方,お待ちしています!
おわりに
ここしばらくjQuery依存な書き方しかしてこなかったので,XHRに直接触れるのが非常に新鮮でした >< 今回の範囲を通じて,JavaScriptによるHTTP通信についての理解を1歩くらいは深められたと思っています.
最後に,参加された皆様,そして開催の告知を,他のコミュニティへの転送,Retweetしていただいた方々,ありがとうございました.次回もまたよろしくお願いします!






