サーバーに任意のファイルをアップロードするCGIを作っていて

気がついた点を一つ。ファイルのアップロード自体は問題なくできるのだが、クライアント側のパソコンの種類によって動作が違う。ファイル名を取り出す時の動作がおかしいのだ。

Perlのスクリプトで、

use File::Basename;

・・・・(途中省略)・・・・

my $filename = basename( $q->param('upfile') );

とやれば、ディレクトリ名は取り除かれてファイル名だけが取り出せるとのことであるが、これがパソコンによってはディレクトリ名が入ってきてしまう場合があるのだ。なんでぇ、おかしいじゃないかぁ~?

で、別のパソコンを使ってやってみるとちゃんとファイル名だけ取り出せるのもある。CGIはサーバ上で動くプログラムでしょ。なんでパソコンに依存して結果が違うの?で、いろいろやってみたがどうやらブラウザがIE6の場合だけがおかしいことが経験上わかりました。IE8やFireFoxでは問題なくファイル名だけが取り出せるのにIE6の場合はディレクトリ名が入ってしまいます。どうやら

basename()って言う関数はディレクトリのつなぎ目をスラッシュ"/"だけで見ていてバックスラッシュ"\"はディレクトリのつなぎ目として認識してないようだ。じゃあIE8やFireFoxはパソコンからパス名を送る時バックスラッシュをスラッシュに変換して送っているのかなぁ。まぁいいや、とりあえず、

my $path = $q->param('upfile');

$path =~ s/\\/\//g;

my $filename = basename( $path );

ってやったらIE6からでもファイル名だけ取り出せるようになりました。

で、さらに調べたら、IE8やFireFoxでは、$path = $q->param('upfile'); で取り出される時点ですでにディレクトリ名は落とされていて、ファイル名のみになっていることが実験でわかりました。

つまり、

IE6では、$q->param('upfile') はディレクトリ名を含んだフルパス名である。

IE8, FireFoxでは、$q->param('upfile') はディレクトリ名を含んでいないファイル名のみである。

CGIは同じでもパソコンのブラウザによってこんな違いがありました。

 

※上記はあくまでも自分の開発環境にて経験上わかったことなので、これが正式な仕様かどうかはわかりません。念のため申し添えます。

 

その後わかったことがありました。IE8では
「インターネットオプション」→「セキュリティ」→「レベルのカスタマイズ」の一覧に、
「サーバーにファイルをアップロードするときにローカルディレクトリのパスを含める」
という項目があり、ここがデフォルトで「無効」になっているのです。
これを有効にしてみたらIE8でもIE6と同じようにアップロードファイルがフルパス名に変わりました。
IE6で同じようなオプションを探してみましたが見つけられませんでした。どうやらIE6ではサーバーにファイルをアップロードする時は、必ず(?)フルパス名を返すようです。IE8ではどちらも選べるのですが、デフォルトではファイル名のみを返すのです。やれやれ。フルパス名をやめてファイル名だけを返す方をデフォルト設定にしたのはローカル側の情報を外に出してしまうことに対する警戒心の現れでしょうか?

まあいずれにせよ、CGI側では受け取った文字列に対して、バックスラッシュをスラッシュに全置換してからbasename()に渡すロジックを入れておけばOKのようですね。

 

参考(IE8のインターネットオプションから)

upload.gif 

  

2020年3月

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Powered by Movable Type 4.38

このブログ記事について

このページは、アローブックぱそこん教室が2009年11月 3日 13:43に書いたブログ記事です。

ひとつ前のブログ記事は「今日も一日ありがとう」です。

次のブログ記事は「今日も一日ありがとう」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ