JSONとAjaxを使ったCGIのメールフォームが完成したので公開します
JSONとAjaxを使ったCGIのメールフォームが完成したので公開します。
配置する場合は、二つのファイルをドキュメントルートに置いてください。
JSONとAjaxを使ったCGIのメールフォーム(CGI.pmを使わないバージョン)
mail.html
HTMLファイルに、メールフォームを記述します。
Sendが押されたタイミングで、メールフォームの情報をJSONにして、Ajax通信で、送信します。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> $(function() { $('.mail-form button').on('click', function () { var form_values = JSON.stringify($('.mail-form form').serializeArray(), null, 2); $.ajax({ type:"post", url:"/mail.cgi", data:form_values, contentType: 'application/json', dataType: "json", success : function (data) { if (data) { $('.mail-form').html('<div>Thank you very much for contacting us.</div>'); } else { alert('Fail sending mail'); } } }); }); }); </script> <h2>Message Form</h2> <div class="mail-form"> <form> <label> <div class="mail-form-title"> Name: </div> <div class="mail-form-body"> <input type="text" size=50 name="name"><br> </div> </label> <label> <div class="mail-form-title"> Mail: </div> <div class="mail-form-body"> <input type="text" size=50 name="email"> </div> </label> <label> <div class="mail-form-title"> Message: </div> <div class="mail-form-body"> <textarea cols=50 rows=3 name="message"></textarea> </div> </label> <div> <button type="button">Send</button> <input type="reset" value="Clear"> </div> </form> </div>
mail.cgi
標準入力から、メールフォームの情報をJSONで受け取って、メールを送信して、標準出力にJSONで、送信結果を書き出します。
CGIに特有の概念のない、通常のPerlスクリプトです。
#!/usr/bin/env perl use strict; use warnings; use utf8; use MIME::Base64; use Encode 'decode', 'encode'; # Mail to my $mailto = 'kimoto@foo.example'; # Mail title my $subject = 'Mail From giblog-mail'; # Mail command my $mail_cmd = '/usr/sbin/sendmail'; my $input = do { local $/; <STDIN> }; $input = decode('UTF-8', $input); my $error = sendmail($input); my $output; if ($error) { $output = 0; } else { $output = 1; } my $res = <<"EOS"; Content-type: application/json; $output EOS print encode('UTF-8', $res); sub sendmail { my ($data) = @_; # Mail header my $mailfrom; my $mail_head = ""; $mail_head .= "Content-Type: text/plain; charset=\"UTF-8\"\n"; $mail_head .= "Content-Transfer-Encoding: base64\n"; $mail_head .= "MIME-Version: 1.0\n"; $mail_head .= "To: $mailto\n"; $mail_head .= "From: $mailto\n"; $mail_head .= "Subject: " . encode('MIME-Header', $subject) . "\n"; $mail_head .= "\n"; # Mail body my $mail_body = $data; # Send mail my $cmd = "$mail_cmd -f $mailto -t"; my $send_error; if (open(my $out, "| $cmd")) { if (print $out $mail_head) { if (print $out encode_base64(encode('UTF-8', $mail_body))) { # Success } else { $send_error = "Mail sending fail(3)"; } } else { $send_error = "Mail sending fail(2)"; } } else { $send_error = "Mail sending fail(1)"; } return $error; }
Perlスクリプトとして、実行して試験できます。POSTされるデータは、標準入力から受け取ります。
chmod 755 mail.cgi echo 'foo' | ./mail.cgi
JSONとAjaxを使ったCGIのメールフォーム(CGI.pmを使うバージョン)
JSONですべて完結できるかなぁと思っていたけど、ファイルアップロードまでを考慮に入れると、無理だったので、素直にCGI.pmとメール送信モジュールMIME::Liteを使ったバージョンも書きました。
mail.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> $(function() { $('.mail-form button').on('click', function () { var form_values = $('.mail-form form').serialize(); $.post("/mail.cgi", form_values, function (data) { if (data) { $('.mail-form').html('<div>Thank you very much for contacting us.</div>'); } else { alert('Fail sending mail'); } }); }); }); </script> <h2>Message Form</h2> <div class="mail-form"> <form> <label> <div class="mail-form-title"> Name: </div> <div class="mail-form-body"> <input type="text" size=50 name="name"><br> </div> </label> <label> <div class="mail-form-title"> Mail: </div> <div class="mail-form-body"> <input type="text" size=50 name="email"> </div> </label> <label> <div class="mail-form-title"> Message: </div> <div class="mail-form-body"> <textarea cols=50 rows=3 name="message"></textarea> </div> </label> <div> <button type="button">Send</button> <input type="reset" value="Clear"> </div> </form> </div>
mail.cgi
#!/usr/bin/env perl use strict; use warnings; use utf8; use MIME::Base64; use CGI; use MIME::Lite; use Encode 'decode', 'encode'; my $q = CGI->new; # Mail to my $mailto = 'kimoto_yuki@shinshina.co.jp'; # Mail title my $subject = 'Mail From giblog-mail'; # Mail command my $mail_cmd = '/usr/sbin/sendmail'; # Name my $name = $q->param('name'); $name = decode('UTF-8', $name); # Email my $email = $q->param('email'); $email = decode('UTF-8', $email); # Message my $message = $q->param('message'); $message = decode('UTF-8', $message); # Mail body my $mail_body = <<"EOS"; Name: $name Email: $email Message: $message EOS # Send mail my $msg = MIME::Lite->new( From => $mailto, To => $mailto, Subject => encode('MIME-Header', $subject), Type => 'multipart/mixed' ); $msg->attach( Type => 'TEXT', Data => encode('UTF-8', $mail_body), ); $msg->send; # Response my $res = <<"EOS"; Content-type: application/json; 1 EOS print encode('UTF-8', $res);