• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:メール送信後にページの内容を書き換えたい)

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

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

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

  • ベストアンサー
  • 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環境変数」 の誤りです。