2009-05-18
あとで読む
HTTPd, Socket, XPCOM, JavaScript | |
- HTTP server for unit tests - MDN
- firefox mozilla/netwerk/test/TestServ.js こっちのが簡単
- firefox mozilla/netwerk/test/httpserver/
- Fx Socket - 枕を欹てて聴く
とりあえず、nsIServerSocket 使いつつ、nsIServerSocketListner ぶち込めばシングルスレッドなサーバーがすぐに作れるな。
2008-10-10
UUID/GUID
JavaScript | |
ブラウザでは動かないけど JScript, XPCOM の場合は以前書いた。
- GUIDの生成 - Ci.nsIZIGOROu - Mozilla 拡張機能勉強会 (JScript)
- UUIDの生成 - Ci.nsIZIGOROu - Mozilla 拡張機能勉強会 (XPCOM)
後は id:LiosK さんの書いた奴。
2008-10-09
setTimeout + document.cookie
JavaScript | |
こういうスクリプトを走らせた時の挙動メモ。但し単独じゃなくてこのページをほぼ同時期に複数タブで実行した場合。
<!DOCTYPE HTML> <html> <head> <title>cookie + setTimeout test</title> <script type="text/javascript"> //<![CDATA[ var c_incr = function() { var c = document.cookie; document.cookie = "c=" + (parseInt ( c.substring(c.indexOf("c=") + 2) || 0 ) + 1 ); }; window.onload = function() { setTimeout(function() { var limit = 10000; for (var i = 0; i < limit; i++) { setTimeout(c_incr, 0); } setTimeout(function() { alert(document.cookie); }, 0); }, 1000 * 3); }; //]]> </script> </head> <body> <h1>cookie + setTimeout test</h1> </body> </html>
で、期待する結果は当然 c の値に limit の数値 10,000 が出る事な訳です。
さらにこのHTML置いた所を複数のタブで開いて、なるべく同じタイミング、少なくとも直前のスクリプトが終わる前に実行すると。
その場合、後から開いたタブの方で期待する所では 20,000 とか出て欲しい訳です。ちなみにやり直す場合は document.cookie の値を初期化する必要ありです。
結果
| browser | c |
| IE7 | 15981 |
| Fx3 | 20000 |
| Opera 9.5 | 19995 |
| Safari 4 | 20000 |
| Chrome 0.2 | 16065 |
まぁこの結果見ると 20,000 と言う結果が出るブラウザの方がひょっとしたらたまたまで、他のブラウザの結果が普通かもしれない。まぁその是非は置いといて少なくとも言える事は、20,000にならないブラウザは、setTimeout() に指定した関数内の処理も非同期になっていて、実行順序が保障されてないと考えられる。
もう少し分かりやすく言うと、
と言う実行順序ならば問題なく、この場合20,000になるんだけども、20,000 にならないブラウザはこの順序どおりには実行されないと言う事だと考えられる。
まぁ逆に 20,000 になるブラウザは無いと思ってたので Fx3, Safari4の実行結果の方にびっくりした。
メモ
これは実は 20,000 となるならば複数のウインドウが存在していた場合、document.cookie を通じて、シーケンス値を発番出来るかなと期待してたんだけど、案の定出来なかったという結論。
2008-10-01
document.cookie の覚え書き
JavaScript | |
ちと余り良く分かってなかったので覚え書き。
key-value の設定
key が foo で value が bar だとすると、
document.cookie="foo=bar";
で設定出来る。
ところで、a=1, b=2 と言う二つを同時に設定する事は出来ません。
document.cookie="a=1;b=2"; alert(document.cookie);
とやると a=1 しか設定出来てません。
expires の設定
var expires = new Date(); expires.setHours(expires.getHours() + 1); document.cookie = "foo=bar;expires=" + expires.toUTCString();
のようにやる。expires 設定されたのは、foo と言うキーに対して。
現在時刻より前の時刻を設定した場合、そのkey-valueは消えます。
document.cookie="foo=;expires=" + expires.toUTCString();
domain の設定
これは謎過ぎるなぁ。。
現在 test.example.com で実行してるとして、
document.cookie = "Z=1"; alert(document.cookie); document.cookie = "Z=2;domain=example.com"; alert(document.cookie); document.cookie = "Z=3;domain=test.example.com"; alert(document.cookie);
は IE6, 7 の場合、最終的に "Z=3;Z=2" となるのだが、Fx3, Safari だと、"Z=1;Z=2;Z=3" となる。
IEの挙動のが正しいと思うんだけど。
domain が省略された Cookie は、その Cookie を生成したサーバのドメイン名が指定されたとみなされます。 [Studying HTTP
とあるように、domain が省略された場合、test.example.com 相当で設定したとされるべきだと思うんだけど。
追記 (2008-10-01T17:55:36+09:00)
と思ったら、domain パラメータの挙動について見ている所が netscape の決めた奴と言う古い奴見てた事が判明。
RFC 2109 - 4.2.2 Set-Cookie Syntax
- Domain=domain
- Optional. The Domain attribute specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot.
つまり、指定するなら "." から開始しないとだめぽって事。
省略した場合の挙動は、
Domain Defaults to the request-host. (Note that there is no dot at the beginning of request-host.) RFC 2109 - 4.3.1 Interpreting Set-Cookie
"." を先頭につけないのが正しいと。
まぁこれらの結果分かるのは、domain 指定がある場合、別々の物として key-value のペアが管理されますよと考えられると。
path の設定
結論から言うと path も domain 同様、ユニークな物として扱われるみたい。
path が省略された Cookie は、その Cookie を含んでいるヘッダによって記述されているドキュメントと同じ path が指定されたとみなされます。 [Studying HTTP
と言う事らしい。
/a/b/c/index.html とかだと path は /a/b/c/ となる。
同期の話
A, B と言うタブを開いていて、共に test.example.com のページだとすると。
A の document.cookie を弄ると、A での変更は B でも読める権限ならば即座に反映されている。
これはちょっとびっくりしました><
まとめ
って感じだな。
2008-09-29
Ex DOM Storage の現状のまとめ (自分用)
JavaScript, Storage | |
sessionStorage 問題
これが最大の問題。
実は要求される仕様を満たせてない。どういう事かと言うと、
- ブラウザを閉じると消える
と言うのは出来ているんだけど、この sessionStorage ってのは、タブ単位で独立したデータなんですよね。IE で言うなら IWebBrowser 単位で管理されてると言える。
つまりタブごとにデータが独立で、特定のタブを閉じればそれに対応した sessionStorage も無くなる。
このタブと言う単位をどうやってもサイト側の JS からでは識別出来ない。本当なら IWebBrowser の HWND (ウインドウハンドル) が取れれば終了なんだけど、どうあがいても取れない。
最初は Shell.Application からやろうとか思ったけど当然セキュリティ上、そんな ActiveX は実行できない。
他にも色々考えてみた。
location.replaceでセッションID的な物をくっつけてからunloadして、飛び先のdocument.referrerを見る
出来ない。何故ならfragmentはreferrerに含まれない。
クエリストリングとしてセッションID的なものをくっつける
論外。
Cookie ベースで
多分これが妥当なんだろうなぁと。但し Cookie を使ったところでタブ単位には出来ないので、
遷移じゃなくて、新しくwindowを開いた場合、つまりターゲットが_self相当では無い場合はwindow.openerが取れるので、新規にセッション開始。
また document.referrer が無い場合、history.length が 1(かな!?)の場合も新規にセッションを開始とかなのかなぁ。
なんか穴がありそうだけど、異なるタブで sessionStorage が共有されるよりはましだとは思うんだけどどうだろう。
また unload イベントも何が起因で unload イベントが起きたか多分判断できないんだよなぁ。
localStorage の同期問題
こっちは一応解決策は考えてるんだけど、やはり同一ドメイン内で同時に localStorage を扱う window がある場合は何らかの形で onstorage イベントが他の window にも通知されるようにしたほうがいい。
あと現時点だと、save の前に一度 load すればいいところをしてないので、データが吹っ飛ぶ可能性があるw
まとめ
今日はずっと sessionStorage がどうにかならないか考えていたんだけど、ちと妥協案にしても面倒なので先に localStorage から片付ける。polling して pull するイメージで。
saveHistory behavior
JavaScript, HTC | |
これは何か
ページごとに存在する persist data を取り扱う behavior のよう。但し、historyで戻る、あるいは進んだ場合にのみ発動するみたい。
サンプル
<!DOCTYPE html>
<html>
<head>
<title>saveHistory Test</title>
<meta name="save" content="history" />
<style type="text/css">
.historyData {
behavior: url("#default#saveHistory");
}
</style>
</head>
<body>
<div class="historyData"></div>
<script type="text/javascript">
var data = null;
var historyData = document.getElementsByTagName("div")[0];
historyData.attachEvent("load", function(evt) {
data = this.getAttribute("pdata");
});
historyData.attachEvent("save", function(evt) {
this.setAttribute("pdata", ++data);
});
</script>
</body>
</html>
のようにして、data という変数をalertしてみれば挙動が分かると思う。
ちなみにこの historyData とつけた変数への setAttribute, getAttribute は saveHistory behavior に対する onsave, onload イベントの時の参照先が persist data であって、そのイベントハンドラ内で実行した場合とそうでない場合で、得られるデータないしは保存先が異なる。
どういった場合に使えるか
ブラウザの戻る、進むボタンを押した時を検出するとかに使える。
ただ、今自分がやりたい事に対しては全然使えないんだなぁ。
DefaultBehaviorのまとめエントリーあると面白いかも。
他のPersistent系は余り使い道無いかも。。。
MSDNのサンプルコードをIEで開く事が出来るんで、まぁそこ見れば十分だと思いますw