« 2011年05月 | メイン | 2011年07月 »

2011年06月 アーカイブ

2011年06月11日

第一回WebSocket勉強会で発表してきました

今更感満載ですが、先々週に開催されたWebSocket勉強会で発表してきました。
スライドができあがったのが当日の朝、登壇に間に合うように数時間だけ仮眠をしてから会場入りしたため、他の発表をほとんど見られなかったのが心残りでしたが...。
公式サイトからリンク済ですが、発表資料と録画された発表の動画をここにも貼っておきます。
主催された西谷様、会場を提供して頂いたIIJ様、ありがとうございます!

2011年06月28日

JavaScriptのオブジェクトをDOMも含めてJSON化っぽくできないかと思って頑張ってみた

JavaScriptのオブジェクトをDOMも含めてJSON化っぽくできないかと思って頑張ってみたけどダメだった...。

DOMは循環参照するため、「JSON.stringify(window)」を実行すると「TypeError: Converting circular structure to JSON」となる。

一度参照したDOMは走査しないようにすると、今度は「TypeError: Accessing selectionEnd on an input element that cannot have a selection.」が発生した。これはフォーカスが当たってないinput要素のselectionEndを参照してしまったため。

じゃあ、例えばDOM要素はそのまま文字化してしまおうと考えた。例えば、div要素は「[object HTMLDivElement]」のようになる。実行してみると「RangeError: Maximum call stack size exceeded」...。

ダメだこりゃ...。

以下、コード。
var DOMJson=function(obj){
    return JSON.stringify(
        obj,
        (
            function(){
                var ary=[];
                return function(k,v){
                    if(ary.indexOf(v)==-1){
                        ary.push(v);
                        var s=Object.prototype.toString.apply(v);
                        if(/\[object HTML[A-Za-z]*Element\]/.test(s)){
                            return s;
                        }else{
                            return v;
                        }
                    }else{
                        return "[reflexive]";
                    }
                }
            }
        )(),
        4
    );
}
console.log(DOMJson({a:3,b:"abc",ary:[1,2,3,location]}));   //=> OK!
console.log(DOMJson({win:window}));                         //=> RangeError: Maximum call stack size exceeded
console.log(DOMJson({doc:document}));                       //=> RangeError: Maximum call stack size exceeded

2011年06月29日

iOS等のブラウザにJavaScriptを送信して実行できるXiangpian(基本編)

iOS上のJavaScriptのデバッグする仕組みが欲しかったので作りました。同じようなのが既にあるのですが、自分の要求を満たせなかったので車輪の再発明です。
iOS上のSafariを操作することを意識して作成されていますが、WebSocketに対応したブラウザであれば操作可能です。デバッグ環境と言っても、ステップ実装等の機能はありません。パソコン等から入力したJavaScriptのコードをWebSocketで送信し、iOSのSafari上で実行する仕組みになっています。JavaScriptの実行結果がパソコン側に戻ってきます。また、consoleオブジェクトをメタプログラミング的に拡張しているため、「console.log」等に渡された値もパソコン側に送信されます。
基本的な使い方
使い始めるには以下の手順が必要です。
・Xiangpianのインストール
・Xiangpianの起動
・ブックマークレットの登録
・Webコンソールの起動
・ブックマークレットの実行
文字で見ると複雑そうですが、実際にやってみるとそんなに面倒ではありません。それぞれ順を追って説明します。以下、操作する側をパソコン、操作される側をiOSと仮定します。

次のURLからXiangpianをダウンロードしインストールしてください。
Windows用にXiangpian.exeがあるためこれを適当な位置に移動してください。Mac OS Xでは、dmgをダブルクリックするとディスクイメージがマウントするので、この中にあるXiangpian.appを適当な位置に移動してください。

Xiangpianを起動します。

ブラウザから「http://[IPアドレスまたはhost名]:40320/」にアクセスすると、設定するための情報が表示されます。(設定画面ではありません。あしからず...。)
アクセスする時のIPアドレスやhost名によってこのページの動作が変わるため、iOSのSafariからアクセスする必要があります。ここでブックマークレットを登録する必要がありますが、iOSのSafariではブックマークレットを直接登録できないため、次の操作が必要になります。(iOSのSafariでなければ、「bookmarklet」にあるブックマークレットをブラウザに登録するだけです。)
まず、画面内の「bookmarklet for iOS」をタップします。見た目に変化はほとんどありませんが、アクセスしているURLが変わっています。この状態でこのページをブックマークに登録してください。登録後、ブックマークの編集画面を開き、URLの先頭の「http://[IPアドレスまたはhost名]:40320/?Xiangpian&-----&」を削除してください。

今度はパソコンからXiangpianのWebコンソールにアクセスします。WebSocketに対応したブラウザから「http://[IPアドレスまたはhost名]:40320/web_console.html」にアクセスします。Xiangpianを起動しているパソコンからであれば、「http://localhost:40320/web_console.html」でも構いません。
iOSのSafariで適当なサイトにアクセスし、ブックマークレットを実行します。
Webコンソールに「Open」と表示されるはずです。
Webコンソールにコードを入力し「send」ボタンをクリックします。
iOSのSafariでは次の用な表示になります。
Webコンソールには、「実行したコード」・「console.logに渡された値」・「実行結果」が色付きで表示されます。
履歴のかわりに、「実行したコード」はクリックするとコードがテキストエリアに追加されるようになっています。通信はJSONを使用しているため、JSON化できないオブジェクトを「console.log」等に渡したり「実行結果」とするとエラーになります。そのような場合は、toStringで文字化して渡すようにしてください。
ライセンス
Xiangpianは以下のライブラリを使用しています。

jewelcli (Apache License 2.0)
jetty (Apache License 2.0 / Eclipse Public License 1.0)
JSONIC (Apache License 2.0)
JLine (BSD License)
Rhino (MPL License / GPL License)

このため、XiangpianのライセンスはMPL LicenseとGPL Licenseのデュアルライセンスになります。(なるはず...という認識なので、間違いがありましたら指摘してもらえると助かります。)
名前の由来
JavaScriptのツールらしくお茶かコーヒー系の名前をつけようと、沖縄の「さんぴん茶」から「さんぴん」にしようと考えていたのですが、スペルをどうしようかと悩んだ挙げ句、語源と言われている中国語の「香片茶(シアンピエンチャー Xiangpiancha)」から取りました。
その他の機能
他にも機能があるのですが、長くなるのでそのうち別エントリーで...。

2011年06月30日

iOS等のブラウザにJavaScriptを送信して実行できるXiangpian(設定上級編)

Xiangpianでは、「操作される側」のXiangpianへの接続方法を2つ用意しています。また、XiangpianのWebSocketのURLの指定方法も2つあります。
接続方法
接続方法のひとつは前回紹介したブックマークレットです。
もうひとつはscript要素を使った方法になります。IPアドレスが、「192.168.0.10」の端末でXiangpianを起動した場合を例に説明します。「http://192.168.0.10:40320/」にブラウザでアクセスすると、設定をするための情報が表示されます。その中の「script tag code」に以下のようなHTMLが出力されています。
<script type="text/javascript" src="http://192.168.0.10:40320/execute.js" data-xiangpian-execute-url="ws://192.168.0.10:40320/ws/" data-xiangpian-execute_from="script_tag"></script>
これを開発中のHTML内に組み込むことで、常にXiangpianを実行することができるようになります。例えば、Ruby on Rails等で、development環境の時だけ出力させる等の使い方を想定しています。後述しますが、セキュリティで気をつけなければならない点がありますので、本番環境に出力されないようにしてください。

ブックマークレットによる接続とscript要素による接続には以下のような違いがあります。

・ブックマークレット
  ・ソース変更なしで操作することが可能
  ・管理下にないページでも実行が可能
  ・ページ遷移のたびにブックマークレットを実行する必要がある
  ・実行時に一時的にscript要素が挿入されるが、すぐに削除されるため影響が少ない
  ・Xiangpianの接続先がブックマークレットを登録した時のアドレスに固定される(例外あり/後述)
・script要素
  ・ページ遷移があっても常に実行される
  ・ソースの変更が必要
  ・ソースが管理下にないと使用できない
  ・本来のHTMLに比べscript要素が増えるため、挙動に影響がでる可能性がある
  ・Xiangpianの接続先をサーバ側で動的に変更することができる

実際に出力されるscript要素は、カスタムデータ属性「data-xiangpian-execute_from」の値が違うだけでほとんど同じです。
ブックマークレット
<script
 type="text/javascript"
 src="http://192.168.0.10:40320/execute.js"
 data-xiangpian-execute-url="ws://192.168.0.10:40320/ws/"
 data-xiangpian-execute_from="bookmarklet"
></script>
blog向けに整形しています
script要素
<script
 type="text/javascript"
 src="http://192.168.0.10:40320/execute.js"
 data-xiangpian-execute-url="ws://192.168.0.10:40320/ws/"
 data-xiangpian-execute_from="script_tag"
></script>
blog向けに整形しています
WebSocketのURLの指定方法
ブックマークレットでもscript要素でも、script要素のカスタムデータ属性「data-xiangpian-execute-url」で指定されたURLにWebSocketで接続します。
しかし、WebSocketの接続先を一時的に変更することも可能です。例えば、「http://www.kanasansoft.com/」を表示している時、WebSocketの接続先を「ws://xiangpianserver:40320/ws/」に変更したい場合、URLパラメータの「execute_xiangpian_url」にURLを指定することで接続先を変更することができます。具体的には、以下のURLにブラウザでアクセスすると、接続先が変更されます。

http://www.kanasansoft.com/?execute_xiangpian_url=ws://xiangpianserver:40320/ws/
セキュリティ
ここまで読んで気づいた人もいるかと思いますが、URLパラメータに「execute_xiangpian_url」を指定されていることに気づかずにブックマークレットを実行してしまった場合等、情報が外部に送信されてしまう可能性があります。例えば、「https://mail.google.com/mail/?execute_xiangpian_url=ws://crackerserver:40320/ws/#inbox」というリンクにアクセスして、ブックマークレットを実行してしまうと、gmailのデータが丸見えになってしまいます。また、「https://localhost/?execute_xiangpian_url=ws://crackerserver:40320/ws/」のような場合でも、ローカルで開発中のアプリケーションの情報が丸見えになってしまう可能性があります。接続先URLの上書き機能は開発向けツールならではなのですが、メリットよりもデメリットが大きいと判断した場合、将来のバージョンでは削除するかもしれません。この辺は、セキュリティの人の意見を聞いてみたいですね。
Google

タグ クラウド