2007-01-03

いつもの派閥争いの話

去年の未読 feed を消化していたら, XML vs JSON という話がぞろぞろ出てきた. 火事と喧嘩は XML の華. 最近ちょっとおとなしかったけれど, たまにはこういうのがないと寂しいよね.

火元は JSON の親玉である Douglas Crockford が XML2007 で行った講演 "JSON, The Fat-Free Alternative to XML" らしい (スライドの ppt) . XML 愛好家の集りで XML でないフォーマットの話をするとは豪胆だ. しかも暗に "おまいらおでぶちゃんとは違うんだぜ" と煽っているわけだから, XML ファンが刺激されるのも仕方ない.

まとめ記事によると, 反撃の狼煙を上げたのは Scripting News らしい. でも読んでみるとあんまし JSON をわかってない節がある. 本人も自覚があるのか, 議論をうながしている. スレッド の燃えっぷりは見事. とても読む気にならず.

いくつかのサイトを見たかんじ, XML サイドからの批判は主に "再発明は無駄だ" というもの. それ以前に "JSON には XML にある XXX の機能がない" という話題もあったけれど, こちらはなんとなく収束したらしい. JSON は割り切りフォーマットだからいいんだよ, というわけ. XML はかつてうっかり付けてしまった機能で痛い目に遭っている. (ex. 外部実体, PI, XLink, ...) シンプルさを引き合いに出されると弱い.

再発明については, 適材適所に使おうと落ち着いている様子. クロスサイトができるのは JSON だけだし, XML というレガシーは捨てられない. 無理に捨てなくてもいい. その中間はしばらく議論が続くのだろう. (つまり大差ない.)

JSON vs XML の議論は Ruby vs Java の比較に似ている. Ruby は (syntax が) 簡潔で最近は Rails みたいなキラーアプリ(?)もあり, 勢力範囲を広げている. Java は Ruby にくらべると (syntax が) 冗長なのに加え, メモリ喰い過ぎ, フレームワークが大袈裟などの批判もある. 一方で大量のレガシーやツール群, 強力なコミュニティは捨て難い. Web ベンチャーで Java を使うところはあまり多くはないだろうけれど, 金融機関のバックエンドを Ruby で書く日もしばらくはこないだろう. 趣味のコードは好きな方を使えばいい. 一部のファン同士は反目しあっているけれど, 野次馬達はそれがある種の芸であることを知っている.

大半の Ruby ユーザが Java を駆逐したいわけではないように, JSON コミュニティが XML を駆逐したいと思っているかは怪しい. キャッチコピーの "XML Alternative" は "5 分でできるウェブアプリ" と同列にある わかりやすさ重視のアジテーションに過ぎず, XML 界隈の祭り好きがそれに便乗しただけと見るのが妥当かもしれない. JSON コミュニティは, たとえばやっつけ文字列仕事をいちいち Java で書く同僚にもどかしさを感じる Ruby ユーザみたいなもの. XML 寄りな基幹のミドルウェア屋に JSON サポートへの興味を 持たせることができれば成功というところだろう. こうしていつものように喧嘩は丸く収まり, Web は今日も平和であります.

JSONRequest (はいまいち)

というわけで JSON に興味を持った XML 寄りな私は JSON.org を眺めてみた. RFC にまでなってるのか. がんばってるなあ. でもその並びにあった JSONRequest は どうもぱっとしない.

JSONRequest は JSON の由来であるクロスサイトのハックを ブラウザの機能として組込む提案だ. これはけっこうきわどい話をしている. そもそも <script> を使ったクロスサイトのハックは, ほとんどブラウザのバグみたいなものだ. なにしろ禁止したつもりのクロスサイトなデータ取得ができてしまうわけだから. ただ JSON の登場以前, .js にセキュリティ上懸念のあるデータを置くケースは ほとんどなかった. だからこのハックは重大なセキュリティ問題にはならず, 既成事実として定着した.

一方で JSON は逆方向に潜在的な脆弱さを持っている. <script> で取り寄せたデータに悪意があった時の問題だ. スクリプトが評価されるために何でもできてしまう. JSONRequest にはこの問題を避けたいという狙いがある. JSONRequest 仕様は (困った副作用のない JavaScript 式である) JSON 文法にマッチしない データをエラーとして扱う. なおクロスサイトでない JSON については既に JavaScript 製のパーサ があり, 利用を推奨している.

このように, JSONRequest は新しいなにかではない. 上のようなセキュリティ上のつじつま合わせを目的としている. ただ JSON はもともとグレーゾーンのハックなので, 標準化のために整合性をとろうとしても色々難しい. そして難しい作業の割に JSONRequest の提案はがさつさが目立つ.

以下悪口. たとえばクロスサイトの JSONRequest は Cookie や認証情報を送信しないことになっている. でもそれでクロスサイトのセキュリティが保たれるなら, XHR をこの路線に拡張してもいいはずだ. 実際 JSONRequest から派生して XHR へ拡張の提案が行なわれている. XHR にクロスサイトの拡張を許し, ついでに responseJson プロパティがあれば その方が既存の仕様に対する変更はすくない.

こうしたインクリメンタルな路線ではなく再発明をしたいのは, おそらくセキュリティなどの都合で HTTP を含め細かく制御したいからだろう. 個人的には, これはちょっと怠慢だと思う. 世の中には既に非同期通信の仕組みとして XHR があり, これはセキュリティ上の懸念からクロスサイトの通信を許していない. XHR が危険で JSONRequest が安全だと考える決定的な根拠はない. ただ世の中に JSON のレガシーが少ない結果, 比較的安全というだけの話だ. 最近おきた gmail のアドレス流出バグは, JSON の持つ潜在的なリスクを象徴している.

こうしたリスクと折り合いを付けながらクロスサイトの通信をしたい気持ちはわかる. ただこれまでの経緯を無視し, JSON だけを特別扱いしようとするのは安直すぎる. 面倒がらずクロスサイトのセキュリティ境界に関する議論を深めるのが筋だろう.

議論に挑んだ形跡はある. Douglas Crockford は昨年三月に WHATWG のメーリングリストで JSONRequest を提案している. でもざっと見た限りこの議論は立ち消えになっている. 一方そこから派生した XHR のクロスサイト拡張は Ian Hickson によって W3C の webapi WG へ 提案され, 細々とは生きているようだ. このように議論の場は用意されている. W3C も WHATWG も一応標準化を目的とし, ブラウザベンダ(といっても MS 以外)が参加している. そこでは議論を続けず, なのに "Tell your favorite browser maker I want JSONRequest!" と書いてしまうのはなんというか, かっこわるいんじゃないかしらね.

細かく見ていくと JSONRequest の仕様には他にも粗が目につく. まず RFC4627 との不整合. RFC ではエンコーディングに各種 UTF-x をみとめ, ファイル先頭の 4 バイトから種別を判断しろと言っている. 一方で JSONRequest は UTF-8 "だけ" を認めている. JSONRequest でのこうした制限を正当化する十分な理由は見当たらない.

また, RFC では JSON パーサに非 JSON のフォーマットや拡張を認めているが, JSONRequest ではそれを禁止している. これはセキュリティ上の事情なのだろう. それなら RFC でも文法への対処は厳格にしておけばいい. 拡張を許すのは互換性の問題も生む. 利点はすくない. (draconian なエラー処理が XML の下した英断の一つだという話は以前少し書いた.)

JSONRequest の仕様では, HTTP の Content-Encoding を identity と gzip に限定している. これを限定する理由はない. UA は Accept-Encoding によって自分の受け付けるエンコーディングを表明することができる. 仕様の世話はいらない. また HTTP の追加ヘッダとして "Domain" を指定しているが, RFC2616 に存在しない名前だ. せめて "X-" で接頭しておくのが無難だろう. そもそも Referer があれば不要なヘッダに見える. いかにもレガシー環境で偽装されそうなこの Domain ヘッダを用意したところで, セキュリティの文脈に役に立つとは考えにくい.

HTTP まわりは他の問題もある. HTTP のコネクションは 1 ホストに対して 2 本までが原則になっているが, JSONRequest は自身のコネクションとそれ以外のコネクションを 別にカウントすべきとしている. 身勝手な話だ.

JSONRequest は仕様の最後で Duplex (Comet のようなもの) が可能であると言及しているが, JSONRequest.post() に指定するコールバック関数は通信の完了しか通知しない. これでは随時プッシュされてくるデータの断片をハンドルできない.

こんなとこかな. はっきりいって, 著者の本気度はかなり疑わしい. JSON は既存のインフラとして既に普及しているし, クロスサイトの XHR もいずれ何らかの形で実現されるだろう. JSONRequest はアドホックで複雑だ. JSON のシンプルさを損ねている. やっぱりナシにしますとひっこめても特に誰も困らないと思う.

まとめ

悪口ここまで. JSON-XML 祭りに便乗してちょっと噛み付いてみた. 世のなか時々ヘンな提案はあるし, そういうのは自然と淘汰されていく. こんな場末で日本語を使いケチをつけてもほとんどまったく生産的でない. とはいえ私は悪口を書くために少し JSON を勉強できたし, 適度にヒマもつぶせて, Web は今日も平和であります.

まとめ: