メール送信後にページの内容を書き換えたい

このQ&Aのポイント
  • フォームからメール送信するCGIを作成しました。メール送信処理中は「送信中です」などのページを表示させておき、送信終了後に「送信完了しました」というように、ページの内容を書き換えたいのですが、どのように書けばいいのかわかりません。
  • 現在のソースでは、送信処理中は次のページへの移動中で止まっているようにも見えるため、送信中であることがわかるようにしたいと考えています。
  • 具体的には、メール送信後に送信中のステータスを表示し、送信完了後には「送信完了しました」というメッセージを表示させたいです。知識のある方、教えてください。
回答を見る
  • ベストアンサー

メール送信後にページの内容を書き換えたい

フォームからメール送信するCGIを作成しました。 メール送信処理中は「送信中です」などのページを表示させておき、送信終了後に「送信完了しました」というように、ページの内容を書き換えたいのですが、どのように書けばいいのかわかりません。 今は、送信完了画面は出ますが、送信処理中は次のページへの移動中で止まっているようにも見えるので、できれば「送信中である」というステータスがわかるようにしたいのです。 以下、現在のソースです。 sub mailing_send{     # メールファイル作成 open(MAIL, ">$mail_dir/$mailfile"); ---(中略) close(MAIL); # メールファイルオープン # open(MAIL, "$mail_dir/$mailfile"); @mail = <MAIL>; close(MAIL); # アドレスファイルオープン open(ADDR, "$addr_dir/$addrfile"); @addr = <ADDR>; close(ADDR); $i = 0; foreach $fld (@addr){ chop($fld); ($to_addr, $to_name) = split(/,/, $fld); open(FH, ">$tmpfile"); print FH @mail; close(FH); # JISコードに変換 $conv = "$nkf -j $tmpfile > ${tmpfile}.j"; $ret = system($conv); # メール送信 $command = "$sendmail -ba $to_addr < $tmpfile.j"; $ret = system($command); $i++; } # HTML表示 $pagetitle = "メール送信完了"; &html_head(); print "<h3>メール送信</h3>\n"; print "ファイル$mailfileをアドレス$addrfileに送信しました。\n"; print "計$i通\n"; html_bottom(); exit; } どなたか詳しい方、教えてください。

noname#241291
noname#241291
  • CGI
  • 回答数9
  • ありがとう数9

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

CGIを、データ受け付け部分とメール送信部分の2つに分割するしかないと思います。 データ受け付け部分では、メール送信に必要な情報すべてを(スクリプトが終了しても消えない)一時ファイルに保存し、「送信中」と表示すると共に、<meta>タグでメール送信部分のCGIに飛ばさせます。 メール送信部分のCGIがsend2.cgiであれば、 <META HTTP-EQUIV = "Refresh" content="0; url=http://www.xxxxx.jp/~xxxx/cgi-bin/send2.cgi?環境変数UNIQUE_IDの値"> などとします。 これでブラウザはメール送信部分のCGIに移動します。 注:<META>タグに反応しないブラウザもあるので、その場合はHTTP_USER_AGENT環境変数でブラウザを調べ、反応しないブラウザ用に、メール送信まで一気にやってしまう処理も必要です。 メール送信部分のCGIでは、REQUEST_URIやREQUEST_URI環境変数から、メール送信に必要な情報が書かれた一時ファイルを拾い、その内容に従ってメールを送信し、送信が完了したら「送信完了」のメッセージを表示させます。勿論、使い終わった一時ファイルの消去もここで行います。 複数の人が同時にCGIにアクセスする事を考え、2つのCGI間でデータの受け渡しをするファイルは固定の名前にしてはいけません。環境変数UNIQUE_IDを使うのがベストです。 また、2番目のメール送信用CGIのURLを手打ちしたり、処理中にリロードされたりする場合があるので、2番目のCGIでは、データの受け渡しをする一時ファイルの存在チェック、REQUEST_URIやREQUEST_URI環境変数の内容のチェック、リロードによる2重起動のチェックも必要です。 かなり処理が複雑になりエラーチェックも煩雑になりますが、頑張って試してみて下さい。

noname#241291
質問者

お礼

回答ありがとうございます。 なんとなくイメージはつかめました。 実装には時間がかかりそうですが、頑張って挑戦したいと思います。

その他の回答 (8)

回答No.9

お気に召すかどうか分かりませんが、違う方法を考えてみました(私もやりたいので)。 送信ボタンを押した時に別のウィンドウを開いて「送信中...」のメッセージを表示するというものです。 ウィンドウを送信ボタンが隠れる位置に配置すればボタンを二重に押すことが防げて都合がよいのではないかと思います。 また一定時間後(3秒程度?)に自動的にウィンドウをクローズすることも可能です。 試してみましたが、私としてはなかなかよさそうに思いました。 ただし、なれるとうるさく感じるかも知れません(自動的に開いて、閉じるので手間はかかりませんが)。 最大の利点は、現在のソースは殆ど手直しせずに可能だということです。オンメモリへの移行も問題なくできます。 興味がおありでしたら、詳細をお知らせします。

noname#241291
質問者

お礼

ありがとうございます。 その方法も簡単そうでいいですね。 とりあえず、今までは個人使用だったので、送信中のステータスがわからなくても問題はなかったのですが、これから多数の人に使ってもらう予定なので、なるべくユーザに不安を感じさせない方法がないかと思っていました。 参考にさせていただきます。

回答No.8

非常に消極的な手段ですが、もし不特定な人が使うのであれば、 ・「送信」ボタンをクリックしても無反応に見えるが、送信に時間がかかるためで異常ではないこと。 ・次の画面に移るまで、そのまましばらく待つこと。 ・その間、なにも操作しないこと。特に「送信」ボタンのクリックは厳禁。 などを、入力画面に目立つように表示してはどうでしょう。本人だけが使用するなら、下部のステータスバーである程度判断できると思います。

回答No.7

すみません。最初にお詫びします。 よく確認したら、プログラム個々の機能としては正常に動作してますが、送信が終了するまで画面に出力されてませんでした。 テストした時は送信先が多くなかったので、一見うまく出来ているように見えてました。 結局、#1の方が言われているように一時ファイルを利用するか、GETで渡してやるしかないようです。 GETの場合、送信データは1024バイト(だったと思います)以下に制限されます。 send.cgi?header=$header&body=$bodyのようにして、METAタグか「location.href」で渡してやればOKです。 ご質問の件は、Unix系であればパイプで可能だと思います。 Winの場合やパイプを使わないのであればjcode.pl、jcode.pmを使用します。その他メール関係として MIME::Entity Net::SMTP MIME::Base64 などがあります。「CPAN」で検索すれば容易に見つかります。 無用なアドバイスで余計な手間をおかけして申し訳ありません。ライブラリ、モジュールの存在やちょっとしたテクが分かったということでご容赦ください。

noname#241291
質問者

お礼

ありがとうございました。 GETでは対応できない情報量になると思うので、一時ファイル使用の方向で考えています。 nkfを使わなくても、jcode.plに同じような機能があったのですね。 よく中身を見たことなかったので・・・ 汎用系プログラマからオープン系に移行したので、Unixのコマンドラインで操作できる範囲の知識しかなくて。 まだまだ勉強が必要ですね。

回答No.6

>メールの中身をいったんファイルに落としているのは、このソースでは省略していますが、 >アドレスファイルから相手の宛名をメール本体に挿入する場合があるからです。 まったく同じことをやってますが、オンメモリです。 誤送信防止の意味もあってアドレス帳は選択式にする等、もう少し複雑ですし、従って実際のスクリプトとはかなり違いますが、以下のようにしてます。 : : if ($in{'mailto'} eq "") { $header .= $to_addr; $body = "$to_name 様\n\n" . $in{'body'}; } else { $header .= $in{'mailto'}; $body = $in{'body'}; } $header .= ~~~ : :

noname#241291
質問者

お礼

いろいろとアドバイスありがとうございます。 オンメモリだとJISコード変換にnkfは使えませんか? Perlに文字コード変換機能等あるのでしょうか。 そのあたりでつまづいています。

回答No.5

さらに、よくよく見たらメッセージを表示する場所がまずかったですね。今のままなら、 close(ADDR); の後です。 コード変換に時間がかからないようなら、変換を一括して行っておいて、メール送信のところで foreach $fld (@addr){ を繰り返した方がいいかもしれません。

回答No.4

#3です。些細なことですがミスしてました。 print "</body></html> ↓ print "</body></html>\n"; #3ではjavascriptは省略してあります。 それと、メールの中身を一旦ファイルに落としてますけど、何か理由があるのでしょうか? #1でも触れてますが、いろいろ面倒なことがあるので変数で処理した方がいいと思うのですが。

noname#241291
質問者

お礼

回答ありがとうございます。 メールの中身をいったんファイルに落としているのは、このソースでは省略していますが、アドレスファイルから相手の宛名をメール本体に挿入する場合があるからです。 その作業がなければ、確かに変数で処理したほうがよいですね。

回答No.3

少々強引な方法ですがjavascriptのエラーイベントを使って目的の機能を実現することも出来ます。 # JISコードに変換 $conv = "$nkf -j $tmpfile > ${tmpfile}.j"; $ret = system($conv); ---- 送信開始メッセージ ---- print "Content-type: text/html\n\n"; print "<html>\n"; : : print "<body>\n"; print "メール送信中です。"; --------------------------- # メール送信 $command = "$sendmail -ba $to_addr < $tmpfile.j"; $ret = system($command); $i++; } ----- エラーイベント----- print "<img src=\"dummy.gif\" width=1 height=1 onError=\"complete_msg();\">\n"; print "</body></html> ------------------------ 送信前にメッセージを表示しておき、完了(あるいはエラー。プロセスからの戻り値$retによる)したら、存在しないイメージを指定して無理やりエラーイベントを発生させてジャバスクリプトの "location.href"で別のCGIを呼出します。 呼び出されたCGI側で送信完了のメッセージを表示するとともに METAタグかjavaスクリプトで好きなところへ飛ばして下さい。 無理やりエラーを発生させるので気持ち悪いかも知れませんが、ずっと簡単にできます。 イメージサイズを 1x1でしていすればエラーが起こっていることは見た目では分かりません。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

No.1の訂正 文中に2つある 「REQUEST_URIやREQUEST_URI環境変数」 は 「REQUEST_URIやQUERY_STRING環境変数」 の誤りです。

関連するQ&A

  • perl localhostでgifを表示するには

    超初心者からプログラムを初めて1週間、 プログラム言語にはperlを使用しています。 mac os x です。 perlの教科書読みながら、アクセスカウンタを作ろうとした所、 何故かgif画像が表示されません。 ネットの素材置き場からとってきましたが、パソコン自身、gif自体は認識してくれてます。 ただ、それをperlに組み込んで使おうとすると、表示されません。 ブラウザはfirefoxとsafariで試しましたが、両方認識してくれませんでした。 ちなみにソースは ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー #!/usr/bin/perl print "Content-type: text/html\n\n"; print "<HTML>\n"; print "<HEAD><TITLE>アクセスカウンタ2</TITLE></HEAD>\n"; print " <BODY>\n"; print "<H1>test</H1><HR>\n"; if ( open ( FH , "count.txt")){ $cnt = <FH>; close( FH ); $cnt++; print"<CENTER>\n"; foreach $fld (split (// , $cnt)){ print "<IMG SRC=\"${fld}.gif\">"; } print"</CENTER>\n"; if ( open(FH, ">count.txt" )){ print FH $cnt; close(FH); } else { print "ファイルの書き込みオープンに失敗しました。\n"; } } else { print "ファイルの書き込みオープンに失敗しました。\n"; } print "</BODY>\n"; print "</HTML>\n"; __END__ ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー です。 テキストファイルを確認しているので、 perl 自体の活動と、アクセスのログ?自体は正常に動いているみたいです。 お願いします。 助けてください!

    • ベストアンサー
    • Perl
  • perl の printでのファイルへの指示にて

    独学でmacでパールを勉強しています。 始めてからまだ1週間くらい。 教科書みながら、print命令でファイルハンドルに指示を出してるのですが、 書き込めはできるのですが、 ファイルが無い場合、 新規に自動でファイルが作成されるはずとの記載があったのですが、 何故か、自動でファイルが生成されません。 調べても、設定が必要等言われてますが、 mac自体も初心者でほとんどわかりません。 どのような設定にすればいいのでしょうか? また、ソースに何か悪い所があるのでしょうか? お助けください。   ちなみに下記がソースです。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーー #!/usr/bin/perl print "Content-type: text/html\n\n"; print "<HTML>\n"; print "<HEAD><TITLE>アクセスカウンタ</TITLE></HEAD>\n"; print " <BODY>\n"; print "<H1>test</H1><HR>\n"; if ( open ( FH , "count.txt")){ $cnt = <FH>; close( FH ); $cnt++; print"<CENTER>あなたは${cnt}人目の訪問者です。</CENTER>\n"; if ( open(FH, ">count.txt" )){ print FH $cnt; close(FH); } else { print "ファイルの書き込みオープンに失敗しました。\n"; } } else { print "ファイルの書き込みオープンに失敗しました。\n"; } print "</BODY>\n"; print "</HTML>\n"; __END__ ーーーーーーーーーーーーーーーーーーーーーーーーーー

    • ベストアンサー
    • Perl
  • Perlでメール送信機能

    Perlで管理者にメール送信する機能つきの掲示板を作成しております。が、メール送信されるところまでできましたが、内部エラーが起こり処理が完結しません。 自分ではどこがおかしいのかわからないので、ヒントをひただければと思い、投稿しました。 ~途中から # 登録処理 $inq =~ s/\n//g; $inq =~ s/\r//g; open(LOG,">>$data_file") || &msg_disp("fe"); print LOG "$mc,$dt,$gname,$email,$bm,$sex,$place,$sch,$tel,$inq,$rh\n"; close(LOG); # メール通知 &mail; &msg_disp("rg"); exit; } # close sub write_data # メール通知処理 sub mail{ # ここからロジック &jcode'convert(*fn,"jis"); &jcode'convert(*tn,"jis"); &jcode'convert(*sj,"jis"); &jcode'convert(*ms,"jis"); # open(MAIL, "|$sendmail $mymail"); #本番用 ##open(MAIL, ">mail.txt"); #テスト用 print MAIL mimeencode("From: $fn <$mymail>\n"); print MAIL mimeencode("To: $tn <$mymail>\n"); print MAIL mimeencode("Subject: $sj\n"); print MAIL "Content-Transfer-Encoding: 7bit\n"; print MAIL "Content-Type: text/plain; charset=iso-2022-jp . \n\n"; print MAIL $ms; close(MAIL); }#close sub mail &mailをコメント化した結果、どうやらmailルーチンの中でエラーが起こるようです。しかし、空メールだけはちゃんと指定アドレス($mymail)へ送信されてきます。 最後、$msg_dispルーチンへはエラーが起こり行きません。 mailルーチンのどこらへんがおかしいのでしょうか?

    • ベストアンサー
    • CGI
  • sendmailについて

    以前ここで同様の質問を見たような気がするのですが、時間がないので、また質問させてください。 プロバイダーのsendmailを使ってメールマガジン送信フォームを作成したのですが、2600件メール送信実験中960件辺りで止まってしまいます。 スクリプトは以下の通りです。 foreach (@mailto) { $ok_cnt ++; if (open(MAIL,"| $sendmail -t")) { print MAIL "FormMailer: HOT-NET BINGO Original Mailer Vs2.00\n"; print MAIL "Reply-to: $master\n"; print MAIL "From: $master\n"; print MAIL "To: $_\n"; print MAIL "Subject: $subject\n"; print MAIL "Content-Transfer-Encoding: 7bit\n"; print MAIL "Content-Type: text/plain; charset=iso-2022-jp\n"; print MAIL "\n\n"; print MAIL "$message\n"; print MAIL "\n"; close(MAIL); open(TMP,">>$tmpfile"); print TMP "$ok_cnt\t$_\n"; close(TMP);           if (($ok_cnt % 100) == 0) {sleep 5;} } 当初4~500件位で止まってしまっていたので、 100件送信ごとに5秒のインターバルをおいてみました。 何がダメで止まってしまうのでしょうか? また、何か良い方法があれば教えていただけませんか?

    • 締切済み
    • CGI
  • read関数で読み込んだ内容をファイルに書き込めない

    バイナリ、asciiのファイルの一部を読み込み、ファイルへ書き出したいのですが、ファイルへ書き出しが上手くいきません。 以下、一部です。 open(FH,$c_file); binmode FH; open(CTFH,">$cd_tmp"); binmode(CTFH); if($i == 1){ $result = read(FH,$cd,677); print $result."\n"; print CTFH $cd; print $cd; } 後でcloseしています。 677byteまでをCTFHに書き込みたいのですが、書き込めていません。 実行した際にprintで$resultには677が出力され、$cdも同様に 677byteの内容が実行時に出力されます。 ちなみにCTFHのファイルは作成されますが0byteと いう形で何も書き出されていない状態になっています。 どうしてなのかわからず煮詰まっています。 アドバイスをください。

    • ベストアンサー
    • Perl
  • foreachでのメール一斉送信処理がうまくいきません

    以下のようなファイルからデータを読み込みメールを送信させたいのですが、一つ目のデータに対してはメール送信が行われますが、2行目以降に対してメール送信が行われません。 下記のuser.txt例ですと1行目のAさん宛てには送信されますが,2行目のBさんにはメール送信がされません。 どうしてなのでしょうか? ユーザーに応じたメッセージを送信する必要があり、BCC送信は利用できません。 #user.txtの内容----------- #Aさん,a@mail.com,0 #Bさん,b@mail.com,0 #------------------------ #読み込んだファイルから一行づつ各項目データを読み込む #@checkにはuser.txtが入っている。 foreach $item (@check){ @check_array = split(/\,/, $item); #1件づつメールを送信する require "./mails_user.pl"; } #外部 mails_user.plの内容----------- open (MAIL, "|$mailprog -t") or &Make_Error('mail_trouble'); print MAIL "To: $check_array[1]\n"; print MAIL "From: 送信元アドレス\n"; print MAIL "Subject: タイトル\n\n"; print MAIL "$check_array[0]へのメッセージ"; close(MAIL); 1; #-----------------------------------

    • ベストアンサー
    • Perl
  • 行頭に変なスペースが…

    入力したデータをログファイルの一番上に入れたいために以下のようにしました。 open(FH2,"***.log"); flock(FH2,2); @files = <FH2>; flock(FH2,8); close FH2; open(FH,">***.log"); @filew = "user=$FORM{'name'}<>TIME=$FORM{'TIME'}\n@files"; print FH @filew; close(FH); こうするとなぜかログファイルの2行目以降の頭にスペースが1文字分入ります。 2個目のログファイルオープンの3行目 print FH @filew; のスペースが原因かと思い、 print FH@filew; としてみましたが、やっぱりスペースが入りました。 このスペースを入らないようにするにはどうしたらいいでしょうか?

    • ベストアンサー
    • Perl
  • Perlでのファイル一括読み込み

    Perlにてファイルの一括読み込みを以下記述で実施しております。 実行環境はAIXです。 ------------------------------- #!/usr/bin/perl open(FH,"/tmp/filename1.txt"); @aaa=<FH>; close(FH); print "@aaa\n"; ------------------------------- 上記内容をWindows XPにて実行した場合、何も表示されません。 print文が動いていないのか、ファイルの読み込みができていないのか不明です。 ファイルのパスは以下のように変更しております。 ------------------------------- open(FH,"C:\filename1.txt"); @aaa=<FH>; close(FH); print "@aaa\n"; ------------------------------- Windowsにて動作するようにはどのようにすれば宜しいのでしょうか? 初歩的な質問かもしれませんが、宜しくお願い致します。

    • ベストアンサー
    • Perl
  • ログファイルを削除するcgiプログラム

    ログファイルを削除するcgiプログラム -------------------- $GYOUSUU = $FORM{'GYOUSUU'}; #--- ログファイルオープン open(FH,"***.log"); flock(FH,2); @FILES = <FH>; flock(FH,8); close FH; undef $FILES[$GYOUSUU]; open (FH2,">***.log"); @filew = "@FILES\n"; print FH2@filew; close(FH2); -------------------- となっているのですが、修正後にログファイルの行の頭に、半角スペースが入ってしまいます。 どこを修正すればいいのでしょうか?

    • ベストアンサー
    • Perl
  • メールの一括送信の時に自分宛へメールを送る

    perl初心者です(^^; CSVの一覧DATAへメール一括送信するスクリプトを製作しています。 スクリプトを実行すると、自分(from)へも送信しているのですが、 どこを編集してもなくなりません(^^; 送信はmail.cgiに明記し、from等の設定情報は、base.cgiに明記しております。 どなたかご教授頂けませんでしょうか?? if (!open(OUTMAIL,"| @base[3] -t")) { &error($!); } print OUTMAIL "Mime-Version: 1.0\n"; print OUTMAIL "To: @base[2]\n"; print OUTMAIL "Subject: $subject\n"; print OUTMAIL "From: @base[2]\n"; print OUTMAIL "Bcc: $bccmail\n"; print OUTMAIL "Content-Transfer-Encoding: 7bit\n"; print OUTMAIL "Content-Type: text/plain\; charset=\"ISO-2022-JP\"\n\n"; print OUTMAIL "\n"; print OUTMAIL "$bun\n"; print OUTMAIL "\n\n"; close(OUTMAIL);

    • ベストアンサー
    • Perl

専門家に質問してみよう