jumble

アクセスカウンタ

zoom RSS 画像アップロード

<<   作成日時 : 2010/05/01 23:56   >>

ブログ気持玉 0 / トラックバック 1 / コメント 0

画像アップロード


画像をアップロードする機会というのは結構あると思う。
その際、選択した画像を表示して確認しながらアップロードしたいと思うのはごく自然なことだが、それがなかなかうまくいかない。
試した限りでは、それができるブラウザはかなり限定される。
ファイルをアップロードするには、form要素に<input type="file" ...>を記述する。
そこからユーザーが選択した画像ファイルのデータを取得し、img要素のsrc属性に設定する必要がある。
当然、その画像データはユーザーのローカルな環境から取得したい。

IE6


まず、IE6では簡単にできる。サンプルはここ

JavaScript抜粋
document.images[0].src = document.forms[0].file01.value;

アップロード用のinput要素から選択されたファイルのフルパスを取得し、それをimg要素のsrc属性に指定しているだけだ。
ただし、この方法はIE7以降では、デフォルトの設定のままだとできない(らしい)。
試したわけではないが。
うちはWindowsは未だにXPだし、IEも6のままである。
IEには興味もないしほとんど使わないので、アップデートは面倒くさい。
ということで、IE7以降の確認はしないことにする。
久しぶりにIE6を使用したが、かなりイライラしてしまった。
まあ、それは置いといて。

IE7以降では、アップロード用のinput要素からはファイルのフルパスを取得できない。
フルパスが取得できると、ユーザーのローカルな環境の構造が分かってしまうので、セキュリティ上危険ということだ。
他のブラウザも今はフルパスが取得できるものはないはずだ。
逆にできるブラウザというのは、セキュリティに関する考慮が無いに等しいので、使わない方がいいだろう。
ということで、IEにせよ他のブラウザにせよ、この方法が今後使えるという可能性は皆無だろう。

Firefox


では他のブラウザではどうか?
実はFirefoxではできる。
当然IE6のようにセキュリティの穴を利用するようなものではなく、真当な方法だ。
方法は3つある。
そのうち2つはFirefox独自の方法。
もう1つはHTML5のFile APIを使う方法だ。

・Firefox独自の方法その1


サンプルはここ

JavaScript抜粋
var file = document.forms[0].file01.files[0];
var name = file.fileName;
var pre = "data:image/" + name.substring(name.lastIndexOf(".") + 1) + ";base64,";
document.images[0].src = pre + btoa(file.getAsBinary());

"data:image/xxx;base64,"の後に、画像ファイルのバイナリデータをBase64エンコードしたものを連結し、imgのsrcに指定している。
xxxの部分は画像のフォーマットで、ファイルの拡張子をそのまま使っている。
これは最初にたどり着いた方法で、調べるのにかなり苦労した。
以下は参考にさせてもらったページ。

フォームの file 入力欄と、 files リスト
[javascript] base64 エンコードしたい
Ajax:画像を取得して表示する(Firefox)
JavaScriptでバイナリを扱う & ...

実はもう少し簡単にできるのだが、それは後から分かったことだ。

・Firefox独自の方法その2


ということで、次は上の方法よりもっと簡単な方法。
サンプルはここ

JavaScript抜粋
var file = document.forms[0].file01.files[0];
document.images[0].src = file.getAsDataURL();

要するにFileオブジェクトのgetAsDataURL()メソッドが上と同じことを自動的にやってくれるようだ。

・HTML5のFile APIを使う方法


現在策定が進んでいるHTML5の中に"File API"という仕様があり、これを使えばできる。
記述は少し面倒だ。
ただし、今現在File APIの機能は、Firefox 3.6で"HTML5 parser"という機能を有効にしないと使うことができない。
有効にする方法は、アドレスバーに"about:config"と入力し、"html5.enable"の項目上で右クリック→"切り替え"を選択。
これは自己責任でということのようだ。
で、サンプルはここ

JavaScript抜粋
var reader = new FileReader();
var file = document.forms[0].file01.files[0];
reader.onloadend = function(ev){
    document.images[0].src = reader.result;
};
reader.readAsDataURL(file);

結構面倒だが、いろいろ考えた結果なのだろう。
以下は参考にさせてもらったページ。

HTML5 Drag and Drop APIとFile APIのデモ
html5-developers-jp | Google グループ:
File APIのサンプル
File APIのサンプル

ということで、HTML5が普及すれば、どのブラウザでも同じ記述で実現できるようになるだろう。
早くそうならないかな。

その他


今のところ、まともにできるのはFirefoxだけだと思う。
いろいろ試してみたが、他のブラウザではどうもできそうにない。
似たようなことができるjQueryのプラグインはあるようだ。
このページ参考。
ただし、やってみれば分かるが、ここでやりたいこととは全く異なる。
詳しく見てないが、このプラグインは、ユーザーが画像を選択した時点で、サーバーに画像データを送信していると思われる。
それを一旦一時的な場所に保管しておき、その後ユーザーが確定した段階で正規の場所に移すということなのだろう。
でも、このプラグインの作者は最初からこのような仕様にしたかったのだろうか?
確かにそのようにするべきだという人もいるようだ。
このページ参照。
だが、個人的にはそんな方法がいいやり方だとはとても思えない。
まず、実際にデータが送信されるので当然だが、かなり遅いし、帯域も無駄だ。
サーバー設計者にしても、ユーザーが確定するとは限らないので、その場合の考慮をする必要がある。
ユーザーにしても、気軽に選択した画像ファイルがセキュリティ上問題のあるものだったとしても、実際に送信されてしまう。
確定しなかったとしても、サーバー側でそのファイルを削除してくれる保証はどこにもない。
そんなことをするくらいなら、画像を表示するのはあきらめて、よく確認してから送信するように催促する方がマシではないだろうか。

誰がどう考えても、サーバーにデータを送ることなしに、ユーザーのローカルな環境から画像を表示するほうがいいに決まっている。
上のようなプラグインが存在するということは、逆にそれができないということなんだろうな。

結論


特に結論というものはないが、早くHTML5が普及してほしいな。
あとは、何だかんだいっても、Firefoxが一番、細かいところまでよく考えられていて、真面目なブラウザだという気がする。

テーマ

注目テーマ 一覧


月別リンク

ブログ気持玉

クリックして気持ちを伝えよう!
ログインしてクリックすれば、自分のブログへのリンクが付きます。
→ログインへ

トラックバック(1件)

タイトル (本文) ブログ名/日時
プラダ 財布
画像アップロード jumble/ウェブリブログ ...続きを見る
プラダ 財布
2013/07/06 07:44

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(0件)

内 容 ニックネーム/日時

コメントする help

ニックネーム
本 文
画像アップロード jumble/BIGLOBEウェブリブログ
文字サイズ:       閉じる