いや、謎ってほどのものじゃないんですが、噂のdel.icio.us direc.torを使ってみて、「あれ、Javascriptから直接del.icio.us apiを叩いてるみたいだけど、どうやってるんだろう?」と疑問に思ったので、調べてみました。
まず、del.icio.us direc.torは以下の様な順にHTTPリクエストを出しています。
最初の2つは、最速インターフェース研究会のma.laさんが、[Ajax] JSAN構想とリモートデータの取得とUserJavaScriptでおっしゃっている通り、scriptタグを使って呼び出しているので、ドメインはどこでもいいわけですが、最後のdel.icio.us apiを叩いている部分はxmlHttpRequestを使っています。
自分の理解では、xmlHttpRequestでリモートデータを取得する場合、呼び出し元のJavascriptファイルが置いてあるドメインと、呼び出し先のウェブサーバのドメインが同じじゃないといけないと思っていたのですが、この動作を見てると、そうはなっていないようです。で、d.jsのソースを見てみると、xmlHttpRequestで /api/posts/all を叩いている部分は見受けられるものの、特にdel.ico.usという指定はされていません。
どうやら、一度del.icio.usを開いてからブックマークレットを実行してるところがポイントらしい、と思い、「同じじゃないといけないのは、呼び出し元のJavascriptファイルが置いてあるドメインではなく、Javascriptを呼び出しているページのドメインではないか?」という仮説を立てて、実験してみました。
まず、以下の様なJavascriptファイルを用意します。
function load() { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest!='undefined') { xmlhttp = new XMLHttpRequest(); } if (xmlhttp) { xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { document.body.innerHTML = xmlhttp.responseText; } } xmlhttp.open('GET', '/'); xmlhttp.send(null); } } load();
次に、こいつを呼び出すブックマークレットを作成します。こんな感じで。そしてブックマークに入れます。
どこか適当なウェブサイトを開きます。この時、http://www.google.co.jp/ といったドメインのトップのページではなく、http://www.google.co.jp/imode といった感じで、ディレクトリ名やファイル名が含まれるURLにアクセスして下さい。(javascriptでトップページを読み込んで表示させる、という実験なので、最初からトップページを開いていると、ページ遷移したことが分かりません。)
で、先のブックマークレットを実行します。すると、実行前に開いていたページが所属するドメインのトップページが表示されると思います。
というわけで、xmlHttpRequestのクロスドメインの問題は、「呼び出し元のJavascriptファイルが置いてあるドメインと、呼び出し先のウェブサーバのドメインが同じじゃないといけない」わけではなく、「Javascriptを呼び出しているページのドメインと、呼び出し先のウェブサーバのドメインが同じじゃないといけない」わけで、Javascriptファイルがどこにあっても関係ないようです。(もしかして常識?)
おそらく、ブックマークレットを使わなくても、呼び出し元のページを編集して、直接scriptタグによりJavascriptを呼び出すようにしてもいいんでしょうけど、編集できる権限があるぐらいなら、そもそもクロスドメインがどうとか考える必要はないわけで、ブックマークレットで呼び出すのが現実的なんでしょうね。