読者です 読者をやめる 読者になる 読者になる

その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

Dojo のdojox.form.Uploader で詰まったので書いておく

2012.6.1 追記しました

最近、業務でDojo Toolkit(バージョン1.6)を使ってweb アプリケイションなんかを書いてます。*1
なんでDojo を使っているのかは分かりません。僕がチームに入ったらもうDojo が使われてました。

そして、分かった事。

「英語が出来ないと(Dojo を使うのは)難しい」

Dojo の公式ドキュメントはもちろん英語ですし(オフィシャルのドキュメントは結構不親切な気が……)、
Dojo ユーザの議論の場はStack Overflow みたいな英語のフォーラムですしで、Web に転がってるDojo 関連の情報はほとんどが英語です。
日本語の資料はほぼ無いと言っても良いんじゃないでしょうか。

で、僕の英語力のアレさがたたって今回、dojox.form.Uploader でまんまとハマったので書いておきます。
(Dojo にハメられた、というよりIE というブラウザにヤられた感が強いですが)

dojox.form.Uploader の基本的な使い方

基本的には
dojox.form.Uploader — The Dojo Toolkit - Reference Guide
に書いてあるとおりです。

クライアントサイド(JavaScript側)は始めに
dojo.require('dojox.form.Uploader');
dojo.require('dojox.form.uploader.plugins.HTML5');
dojo.require('dojox.form.uploader.plugins.IFrame');
と、dojox.form.Uploader 関連のブツをinclude して使います。
ここでplugins を2つinclude してるのは、HTML5 が使えないブラウザ(つまりIE 7 とかIE 8 とか。9 も? ふーん、そう)に対応する為です。*2
このように宣言しておくと、HTML5 に対応しているブラウザの場合はHTML5 を用いたUploader を生成し、
HTML5 非対応のブラウザの場合はIFrame を用いたUploader を生成するようになります。
この判断はDojo 側が自動的にやってくれるようです。(多分)*3

<追記>
http://dojotoolkit.org/reference-guide/1.7/dojox/form/Uploader.html
の"Usage" の下の部分に書いてあるように、dojo.require でinclude するのは、
'dojox.form.uploader.plugins.IFrame' もしくは'dojox.form.uploader.plugins.Flash' だけで良いようです。
これら2つのソースコードの中では既に'dojox.form.uploader.plugins.HTML5 が呼ばれており、
ブラウザの種類によって自動的にHTML5 と(IFrame | Flash) を判別してくれるようになっています。
ですので、正しくは
dojo.require('dojox.form.Uploader');
dojo.require('dojox.form.uploader.plugins.IFrame');
という風に宣言してあげれば十分なようです。


で、あとは
dojo.byId("myDiv").appendChild(new dojox.form.Uploader({
	id: 'uploaderTest',
	label: 'uploader'
	multiple: true,
	uploadOnSelect: true,
	url: '/foo/bar'
}));
みたいな感じで書いてやるとDojo のUploader が使えるようになります。

詰まった所(サーバサイド)

クライアントサイドでアップロードされたファイルの情報は、Java だとHttpServletRequest に包まれて送られて来るので、
サーバ側ではソイツを使って諸々の処理をしなければならない訳です。

で、サーバサイドで今回詰まりました。何が悪かったかというと、

HTML5 でアップロードされた時と、IFrame でアップロードされた時とでは、送信されてくるデータのパラメータ名が異なっている

という事に気付かなかった為でした。
具体的にどこがどう違うかと言うと、
  • HTML5
    • ファイル名: name
    • アップロードされたファイルの情報: uploadedfiles[]
  • IFrame
    • ファイル名: Filename
    • アップロードされたファイルの情報: uploadedfileFlash
という具合になっています。

なので、HTML5 かIFrame かでパラメータ名が変わってくるので、それに対応したサーバサイドのコードを書かなければなりません。
(とは言っても、getParameter("name") 、getAttribute("uploadedfiles") して中身がnull だったらHTML5 に対応していないって事なので
getParameter("Filename")、getAttribute("uploadedfileFlash")を実行してIFrame に対応したデータを取ってくれば良いだけですが)

僕は最初、HTML5 に対応したパラメータ名(name, uploadedfiles
)でしかコードを書いていなくて、
なおかつ開発環境がChrome だったのでこの事に全く気付きませんでした。
そしてある日、IE 8 でアップローダのテストをしたら上手く動かない。
なぜだ。JavaScript が悪いのか? などと丸1日頭を悩ませて行き着いたのが上記のような解決方法でした。

IE がHTML5 では無くIFrame を使ってアップロードしているとは……
そして、なぜアップロード方法に依ってパラメーター名が変わるんだ……Dojoェ……
(そもそもHTML5 に対応してないIE が悪い!!!!!)


という訳で、「Dojo のUploader がFirefox やChrome では動くのにIE では動かない! クソが!」という時は、
もしかしたらサーバサイドが問題かも知れません。使っているパラメータの名前を確認してみましょう。

もしも英語ができたなら

こんな風にハマらなくても済んだんや!!!!!
なぜなら
http://dojotoolkit.org/reference-guide/1.7/dojox/form/Uploader.html#id13
に書いてあるから!!!!!!!

英語出来るようになりたい(切実)

*1:Dojo についてはこちらをご覧下さい。[http://dojotoolkit.org/:title]

*2:IE に対応したくない方はinclude しなくても大丈夫です。それどころか、以下に書いてあるIE 向けの対応をしなくても平気です。こんなに幸せな事はない!

*3:もしかしたら、dojo.require('dojox.form.uploader.plugins.HTML5'); は要らないかもしれません。念のため