【保存版】コピペで動く!Perl/CGIで作るメールフォーム自作入門

WordPressのプラグインに頼らず、自作のLPや静的なHTMLサイトに「シンプルで軽量なお問い合わせフォーム」を設置したい。そんな時に役立つ、Perl/CGIを使ったメールフォームの作り方を解説します。
今回は、「余計な機能を削ぎ落とした最小限のコード」でありながら、昨今の厳しいセキュリティ事情(なりすまし判定)にも対応した、実用的なテンプレートをご用意しました。
必要なファイル構成
今回は以下の3つのファイルだけで構成します。
index.html:入力画面sendmail.cgi:送信処理プログラム(Perl)thanks.html:送信完了画面
1. 入力画面(index.html)
まずはユーザーが情報を入力するHTMLファイルです。 重要なのは <form> タグの設定です。action 属性でCGIファイルを指定し、method は必ず POST に設定します。
HTML(index.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>メールフォーム</title>
<style>
body { font-family: sans-serif; margin: 20px; background-color: #f4f4f4; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
div { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type="text"], input[type="email"], textarea {
width: 100%;
padding: 8px;
box-sizing: border-box; /* パディングを含めて幅100%にする */
border: 1px solid #ccc;
border-radius: 4px;
}
button {
background-color: #007bff;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover { background-color: #0056b3; }
</style>
</head>
<body>
<div class="container">
<h2>お問い合わせフォーム</h2>
<p>これはCGIで動作する最小限のメールフォームです。</p>
<form action="/sendmail.cgi" method="POST">
<div>
<label for="name">お名前 (name):</label>
<input type="text" id="name" name="name" required>
</div>
<div>
<label for="email">メールアドレス (email):</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="message">お問い合わせ内容 (message):</label>
<textarea id="message" name="message" rows="5" required></textarea>
</div>
<div>
<button type="submit">送信</button>
</div>
</form>
</div>
</body>
</html>
2. 送信処理プログラム(sendmail.cgi)
こちらが心臓部となるPerlスクリプトです。 このコードの優れた点は、「Xserverなどのレンタルサーバーで、メールが迷惑メール扱いされにくい設計」になっていることです。

コードのポイント
- Fromヘッダーの最適化: 送信元(From)をユーザーのアドレスにするのではなく、**「自分のサーバーのドメインメール」**に設定し、返信先(Reply-To)をユーザーのアドレスに設定しています。これにより、SPF/DKIMなどのなりすまし対策に引っかからず、確実にメールを届けることができます。
- 文字化け対策:
Encodeモジュールを使用し、日本語を適切に処理しています。 - リダイレクト処理: 送信後に
thanks.htmlへ画面遷移させることで、再読み込みによる二重送信を防ぎます。
Perl(sendmail.cgi)
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use CGI;
use Encode;
# --- 設定 ---
my $to_admin = 'your-email@◯◯◯.com'; # ★要変更(サーバ内のドメインメール)
my $sendmail = '/usr/sbin/sendmail';
my $thanks_page = 'https://◯◯◯.com/thanks.html'; # ★要変更(絶対URL)
my $subject = 'Webサイトからのお問い合わせ';
# ------------
my $q = CGI->new;
# フォームデータ取得(UTF-8デコード)
my $name = decode('UTF-8', $q->param('name') // '');
my $email = decode('UTF-8', $q->param('email') // '');
my $message = decode('UTF-8', $q->param('message') // '');
# メール本文作成
my $body = <<"EOT";
Webサイトからお問い合わせがありました。
お名前: $name
メールアドレス: $email
$message
EOT
# --- sendmail処理 ---
open(my $MAIL, "| $sendmail -t") or die "sendmail error: $!";
print $MAIL "To: $to_admin\n";
print $MAIL "From: $to_admin\n"; # ← サーバ内のドメイン
print $MAIL "Reply-To: $email\n"; # ← ユーザーのメールアドレス
print $MAIL "Subject: $subject\n";
print $MAIL "Content-Type: text/plain; charset=UTF-8\n";
print $MAIL "Content-Transfer-Encoding: 8bit\n";
print $MAIL "\n"; # ヘッダー終了
print $MAIL $body;
close($MAIL);
# ここで初めてヘッダーを出す(重複禁止)
print $q->redirect($thanks_page);
exit;
設定箇所
コード内の以下の変数を、ご自身の環境に合わせて書き換えてください。
$to_admin: 管理者(あなた)のメールアドレス。必ずサーバーのドメインと同じものを使用してください。$thanks_page: 送信完了ページのURL。http://から始まる絶対パスが確実です。
3. 送信完了画面(thanks.html)
メール送信が成功した後に表示されるページです。
HTML(thanks.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>送信完了</title>
<style>
body { font-family: sans-serif; margin: 20px; background-color: #f4f4f4; text-align: center; }
.container { max-width: 600px; margin: 50px auto; padding: 30px; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
h1 { color: #28a745; }
</style>
</head>
<body>
<div class="container">
<h1>送信が完了しました</h1>
<p>お問い合わせいただき、誠にありがとうございます。</p>
<p>内容を確認の上、担当者よりご連絡させていただきます。</p>
<br>
<p><a href="/">トップページに戻る</a></p> </div>
</body>
</html>
設置時の最重要ポイント(ここだけは注意!)
CGIプログラムを動かすためには、コードが合っていても「設置方法」を間違えると動きません。以下の2点だけは必ず守ってください。
1. パーミッション(権限)の設定
FTPソフトでファイルをアップロードした後、sendmail.cgi のパーミッション(属性)を変更する必要があります。
- sendmail.cgi のパーミッション: 705 または 755
- (htmlファイルは通常そのままでOKです)
2. 改行コードと文字コード
Perlスクリプトは、Windowsの改行コードが含まれているとエラー(500 Internal Server Error)になります。
- 文字コード: UTF-8(BOMなし)
- 改行コード: LF(UNIX形式)
多くのテキストエディタ(VS Code, Sakura Editorなど)で保存時に指定できます。アップロード時のFTPソフトの設定にも注意してください。
まとめ
以上で、最小限のメールフォームが完成です。 このコードは「確認画面」などの複雑な機能を省いていますが、その分コードの見通しが良く、デザインのカスタマイズや、機能の拡張(自動返信メールの追加など)のベースとしても最適です。
ぜひ、ご自身のサイトで活用してみてください。
なおメールフォームはPHPで作ることもできます。下記記事をご確認ください!

