• 締切済み

CGI によるファイルのアップロード

こんにちは。Perl初心者です。 ファイルのアップロードのプログラムを作ったのですが(と言っても書籍の丸写しですが..)サーバー上でエラーになってしまいます。どこが間違っているか教えて下さい。 環境:@niftyのホームページ(CGIは許可されています。), PC: Windows XP ソース: #!/usr/local/bin/perl use CGI qw(:standard); $file1 = param('file1'); open OUT, "> $file1"; while(<$file1>){   print OUT $_; } close OUT; $file2 = param('file2'); open OUT, "> $file2"; while(<$file2>){   print OUT $_; } close OUT; print <<"EOL"; Content-type: text/html <html> <body> Files have been uploaded.<br> $file1<br> $file2<br> </body> </html> EOL exit;

  • CGI
  • 回答数5
  • ありがとう数3

みんなの回答

回答No.5

そりゃ当たり前でしょうね。 $file1と$file2の引数として 受け取っているのは Windowsでのアップするファイルのパス そんなものUNIX系のシステムでエラー 出るのは当たり前。 C:\~\~ こんな場所にアップなんてできるはずないし ファイル名は自分で作るか パスを分割するスクリプトを書くかですね。 UNIX系、Mac系(Xは多分UNIX系? 9までは独自), Windows系ではパスの書き方が違うのでそこら辺を 考慮してファイル名を検出するプログラムを書かないと ダメ。 #3の人がそのことを書いているが 完全に無視している質問者。

  • rafysta
  • ベストアンサー率45% (24/53)
回答No.4

・とりあえず、冒頭に use CGI::Carp qw(fatalsToBrowser); と書くことを勧めます。これを書いておくとブラウザ上にエラーの内容が表示されます。 ・ファイルをopenする時に、openが成功したかどうかを捕捉するようにした方がいいです。 or die "cannot write $file : $!"; これを書いておけばopenが成功しているかどうか確認できます。(Permissionの設定でエラーを起こしていることが多々あります。) ・HTMLにenctypeを指定していますか?(アップロードする時のみ、指定する必要があります) enctype="multipart/form-data" 上を踏まえて、少し書き直したのが下になります。 CGI #!/usr/local/bin/perl use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); my $file = param('file'); my $fh = upload('file'); open OUT, '>', $file or die "cannot write $file : $!"; while(<$fh>){ print OUT $_; } close OUT; print <<"EOL"; Content-type: text/html <html> <body> Files have been uploaded.<br> $file<br> </body> </html> EOL exit; HTML <html> <body> <form name="form1" enctype="multipart/form-data" method="post" action="test.cgi"> <input type="file" name="file" /> <input type="submit" name="Submit" value="送信" /> </form> </body> </html>

hibachi
質問者

補足

回答ありがとうございます。 指摘された事をほぼ丸写しして実行してみるのですが、やはりサーバー上で 実行エラー CGIの実行時にエラーが発生しました。 と表示されます。ファイル名を指定して出力したりしたのですが、変わらずエラーとなります。 ただ、ローカルでは動いているのでサーバー側の何かの設定にひっかかっているのかもしれませんが・・・

  • rafysta
  • ベストアンサー率45% (24/53)
回答No.3

下の追加です。 $file1 = param('file1'); で受け取ったファイル名をそのまま open OUT, "> $file1"; として出力していますが、このままだとファイル名が例えば "C:\Documents and Settings\なんとかかんとか.txt" というようにパス付きの名前になってしまう(Windowsの場合)ので、ファイル名だけを取り出す処理をする、もしくは、ファイル名を自分で指定した方がいいと思います。

  • rafysta
  • ベストアンサー率45% (24/53)
回答No.2

$file1 = param('file1'); これだと、単に$file1にはファイル名が入るだけなので、while(<$file1>){ で、エラーになります。 $file1 = upload('file1'); として、ファイルハンドルを取得する必要があるのでは? 単純に上記部分を変更するだけだと、最後の $file1<br> $file2<br> の部分が、今度はエラーになってしまうので、こちらの部分は $file1 = param('file1'); で取得する必要があると思いますが・・。

hibachi
質問者

補足

ご指摘の通りに直したんですが、やはり実行時エラーとなりました。

  • moon_night
  • ベストアンサー率32% (598/1831)
回答No.1

どこでどんなエラーが出ていますか? ローカル上では動くのですか?

hibachi
質問者

お礼

再確認したところ、2つのファイル C:\Documents and Settings\User\My Documents\test.html C:\Documents and Settings\User\My Documents\Wndows.txt は、上書きされていました。

hibachi
質問者

補足

サーバー上では 実行エラー CGIの実行時にエラーが発生しました。 と表示されます。 ちなみにローカルでは、 Files have been uploaded. C:\Documents and Settings\User\My Documents\test.html C:\Documents and Settings\User\My Documents\Wndows.txt と表示され動いているようですがファイルの作成はされませんでした。

関連するQ&A

  • ファイルのアップロードができません。

    Perl CGIモジュールを使ってファイルのアップロードをしたいのですが、うまくいきません。 以下HTML部分 =================================================================== <form action="test.cgi" enctype="multipart/form-data" method=post> 1つめのファイルを選択<input type="file" name="upimg1" size=40><br> <input type=submit value=アップロード></form> ==================================================================== 受け取るCGI ==================================================================== #!/usr/bin/perl use CGI qw(:standard); $upimg1 = param('upimg1'); open UP,"> ./img_dir/sample.jpg"; while(<$upimg1>){ print UP $_; } close UP print <<"EOL"; Content-type: text/html <html> <body> Files have been uploaded.<br> $file1<br> $file2<br> </body> </html> EOL exit; ===================================================================== 実際アップフォルダ内にはsample.jpgがあるのですが、0バイトできちんとアップされていません。 本をみて自分なりにやってみたのですが・・・ どこがまちがっていますか?よろしくお願いします。

    • ベストアンサー
    • CGI
  • ファイルをアップロードするCGI

    ファイルをアップロードしたいCGIが欲しく サンプルをみつけたのですが、このCGIだと ファイルをアップロードしたときに、ファイル名がアップロードした時刻になってしまいます。 ファイル名を変更することなく、アップロードするにはどう変更すればよいのでしょうか? お願いします。ちなみにアップロードしたいファイルの種類はエクセル形式のファイルです。 プログラムは以下のようになってます。 #!/usr/bin/env perl use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); use POSIX qw(strftime); my $q = new CGI; print $q->header(), $q->start_html(); #print $q->dump; # for debug my $outputdir = "log"; # ファイルを置く先 (ディレクトリ) my $fh = $q->param('uploaded_file'); my ($ex) = ($fh =~ m|(\.[^./\\]+)$|); # 拡張子 if ($fh ne "") { my $timestamp = strftime "%y%m%d%H%M%S", localtime; my $outputfn = "$outputdir/$timestamp$ex"; open(F, "> $outputfn") or die; flock(F, 2); if (defined $fh) { while (<$fh>) { print F $_; } } close F; print qq{saved as <a href="$outputfn">$outputfn</a>}; } print $q->start_multipart_form(-name => 'myform'), $q->filefield(-name => 'uploaded_file'), $q->submit("OK"), $q->endform, $q->end_html(), "\n";

  • perlでCSV形式ファイルのアップロード

    本日、同じ質問をしたものです。 前回の問題は解決したのですが、ファイルがアップロードできないで悩んでします。 CGIのプログラムは以下のソースです。 #! c:/perl/bin/perl use CGI; # CGIヘッダーの出力 print "Content-type: text/html\n\n"; my ($query,$fileName); $query = new CGI; $fileName = $query->param('fileName'); open(OUT, ">./a.csv"); binmode(OUT); while(read($fileName,$buffer,1024)) { print OUT $buffer; } close(OUT); close($fileName); #ファイルハンドルをcloseしています。 exit ; ファイルは、作られるのですが、中身が書き込まれません。 どなたか教えてください。 お願いします。

    • ベストアンサー
    • Perl
  • アップロードフォームの使用に失敗する。

    表題の機能の使用に失敗してしまいます。 [以下、フォーム部分] <form action="upload.cgi" method="post" enctype='multipart/form-data'> <input type="file" name="data" /> <input type=submit /> </form> [upload.cgi(データの送信先)] #!/usr/bin/perl use CGI qw(:standard); $data = param('data'); while (read($data, $buffer, 2048)) { $file .= $buffer; } open UP, "> ./test.txt"; print UP $file; close UP; print <<"EOF" Content-type: text/html <html> <body> Files have been uploaded.<br> $filename<br> </body> </html> EOF このフォームを実行すると、HTML上には以下の出力が行われます。 --------------------------------------- Files have been uploaded. C:\Documents and Settings\ht-sato\デスクトップ\aaa.txt しかし、肝心のファイルはサーバ上に作成されていません。 書き込み権が問題かとも思い、各ファイルやディレクトリの パーミッションも確認しましたが、書き込み可能となっていました。 どうか、解決するためのアドバイスを頂けますでしょうか。

    • ベストアンサー
    • CGI
  • CGI のモジュールをつかってファイルのアップロード

    use CGI qw(:standard); use File::Basename; $upimg1_pm = param('upimg1'); while (read($upimg1_pm, $buffer, 2048)) { $file .= $buffer; } $FileName = basename($upimg1_pm, ""); open UP,"> $img_dir/$FileName"; binmode UP; print UP $file; close UP; 上のようにファイルのアップロードのプログラムを書いたのですが、実際アップロードしたら C:\Documents and Settings\~top.gif のようにWindowsのローカルパスがそのままファイル名としてアップロードされてしまいました。 basenameはファイル名をとるモジュールときいていたのですがなぜこうなるのでしょうか? おそれいりますがご教授おねがいします。 もしかしてFile::Basename;のモジュールがないとか・・・ Perl5です。

    • ベストアンサー
    • CGI
  • 伝言掲示板の作成(超初心者です)

    授業の課題で伝言掲示板を作るのですが 行き詰ってるので助けてください。 ファイル名write.htmlで <html> <body> 掲示板プログラム<br> 書き込み内容を指定してください <form action="write.cgi"> <input type="text" name="contents"> <input type="submit"> </form> </body> </html> write.cgiで #!/usr/bin/perl print "Content-type: text/html\n\n"; use CGI qw(:standard); $value = param("contents") ; open(OUT,">contents.txt"); print OUT $value; close(OUT) ; print "<html><body>"; print "書き込みが終了しました"; print "</body></html>"; read.cgiで #!/usr/bin/perl print "Content-type: text/html\n\n"; open(IN,"contents.txt"); $value = <IN>; close(IN); print "<html><body>"; print $value; print "</body></html>" 空のテキストファイルcontents.txtを作成しました。 これで伝言掲示板はできますよね?? では前の書き込みが消えないようにするにはどうした良いですか? あと、装飾したい場合はwrite.htmlにタグを利用して書けばよいのですか?? わかりにくい書き込みですみません。

    • ベストアンサー
    • CGI
  • perlでCSV形式ファイルのアップロード方法

    perlでCSV形式ファイルのアップロード方法を教えてさい。 htmlで <HTML> <BODY> <FORM action="excel読み込み.cgi" enctype="multipart/form-data" method="post"> フレアシステムのファイル: <INPUT type="file" name="upload_file" size="60"><BR> <INPUT type="submit" value="読み込み"> </FORM> </BODY> </HTML> として、ファイル名の指定をして、読み込みボタンを押すと、excel読み込み.cgiを呼び出すのですが、プログラムの内容が表示されるだけで終わってしまいます。 excel読み込み.cgiのプログラムは以下の内容です。 #! c:/perl/bin/perl use CGI; $query = new CGI; $filename = $query->param('upload_file'); while(read($filename, $buffer, 2048)) { $file .= $buffer; } @files = split(/\\/, $filename); ($basename, $exp) = split(/\./, $files[-1]); $new_file = $basename . "." . $exp; # ファイルを指定ディレクトリにコピー #open(OUT, "> c:\\foo\\$new_file"); open(OUT, "> c:\\$new_file"); binmode(OUT); print(OUT $file); close(OUT); print "Content-type: text/html\n\n"; print "[$basename] [$exp]\n"; print "正常終了\n"; exit; CGIのプログラムを色々と調べて、別のないようにしても同じようにプログラムがそのまま表示されてしまいます。 どなたか教えてください。 宜しくお願いします。

  • CGI..pmを使っての画像のアップロードについての質問です。

    お世話になります画像ファイルをサーバーにアップロードしたいのですが、巧くいきません。以下のコードを実行しますと O.K. File(C:\Documents and Settings\Administrator\My Documents\My Pictures\mozi_g0.gif) was uploaded as /tmp/upload_1111735699_26448 と表示されますが、これで本当に画像ファイルがアップされているのでしょうか? 私見だとサーバー側にtmpというフォルダーに画像ファイルがアップロードされるものと思い /cgi-bin/upload.cgi と同じ所にtmpというフォルダーを作りパーミッションは755にしましたが アップロードをしても空フォルダーのままです、ローカルのフォルダーの画像をサーバー側に保存する方法を御教授お願い出来ませんでしょうか html側のコード <html> <body> <form action="/cgi-bin/upload.cgi" method="POST" ENCTYPE="multipart/form-data"> file <input type="file" name="uploadFile"><br> <hr> <input type="submit" value="OK"> </form> </body> </html> ファイルアップロード本体(upload.cgi) #!/usr/bin/perl use CGI; my($form) = new CGI; print $form->header("text/html"); my($filename) = $form->param('uploadFile'); $uniqid = time . "_" . $$; $newfile = "upload_$uniqid"; # ファイルの内容を表示する。 # このように、$filename をファイルハンドルのように使うこともできる。 #while(<$filename>){ # print $_ . "<br>\n"; #} # ファイルを保存する。 open (OUTFILE,">/tmp/$newfile") or die "Can't make serverside file!\n"; while ($bytesread = read($filename,$buffer,1024)) { print OUTFILE $buffer; } print "O.K. File($filename) was uploaded as /tmp/upload_$uniqid<br>\n";

    • ベストアンサー
    • Perl
  • ファイルのアップロードについて

    PERLでファイルのアップロード機能を作成しています。 アップロードと言っても、サーバへのコピーではなく、 データベースへバイナリで格納しなければならないのです。 とりあえず2パターン作成してみたのですが、 OPEN関数を使ってやるとうまくいきません。 -----パターン1(OPEN関数使用)------------- $query = new CGI; $filename = $query->param('msds'); # ファイル名(フルパス)取得 if($filename ne "") { open(ATT, $filename);# or die "Could not open atachment file:"; binmode(ATT); while($bytesread = read(ATT, $buffer, $BUFSZ)){ $file .= $buffer; # ファイルサイズ制限 $file_size ++; if($file_size > 300){ exitError("ファイルサイズが大きすぎます。600KB 以下にして下さい。"); } } close(ATT); } -----パターン2(OPEN関数未使用)------------- $query = new CGI; $filename = $query->param('temp1'); # ファイル名(フルパス)取得 if($filename ne "") { while($bytesread = read($filename, $buffer, $BUFSZ)){ $file .= $buffer; # ファイルサイズ制限 $file_size ++; if($file_size > 300){ exitError("ファイルサイズが大きすぎます。600KB 以下にして下さい。"); } } print "FILE DATA:" . $file . "<BR>"; } パターン2でprint $fileをすると、ファイルの内容が 画面表示されるのですが、パターン1だと、While文に 入ってくれませんでした。 原因がさっぱりわかりません。。。 お分かりになる方が見えましたらご教授願います。

    • ベストアンサー
    • CGI
  • Perlのファイルのアップロードの方法についてお聞きします。

    Perlのファイルのアップロードの方法についてお聞きします。 &ReadParseを用いた方法で、 $file = $in{'TENSOU'};で$file自体にデータが入るので 簡単だなと思っていましたが、送信元と送信後のファイルが若干違っていました。 使い方が間違っているのでしょうか? 以下、サンプル ◆HTML側 <FORM ACTION="up.cgi" ENCTYPE="multipart/form-data" METHOD="POST"><P> ファイル: <INPUT TYPE="file" NAME="TENSOU" SIZE="32"><BR> <INPUT TYPE="submit" VALUE="送信"> </FORM> ◆Perl側 &ReadParseの例を用いた方法 #!/perl/bin/perl #!/usr/local/bin/perl use CGI; use CGI::Carp qw(fatalsToBrowser); #--->エラー対策 require 'cgi-lib.pl'; require 'jcode.pl'; $BUFSIZE = 2048; &ReadParse; # ==> 強力な変換 $file = $in{'TENSOU'}; # ==> 実態自体がデータなので、取り扱いしやすい $file_size = length($file); $file_size *= ($BUFSIZE / 1024); open(OUT, "> test.jpg"); print(OUT $file); close(OUT); print "Content-type: text/html\n\n"; print "$file_size(KB)<br>\n"; print "<a href=\"test.jpg\">テスト</a>\n"; exit;

    • ベストアンサー
    • CGI

専門家に質問してみよう