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

WordPressのプラグインに頼らず、自作のLPや静的なHTMLサイトに「シンプルで軽量なお問い合わせフォーム」を設置したい。そんな時に役立つ、Perl/CGIを使ったメールフォームの作り方を解説します。

今回は、余計な機能を削ぎ落とした最小限のコード」でありながら、昨今の厳しいセキュリティ事情(なりすまし判定)にも対応した、実用的なテンプレートをご用意しました。

目次

必要なファイル構成

今回は以下の3つのファイルだけで構成します。

  1. index.html:入力画面
  2. sendmail.cgi:送信処理プログラム(Perl)
  3. 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で作ることもできます。下記記事をご確認ください!

あわせて読みたい
【PHP入門】最小構成で学ぶ!メールフォームの作り方(確認画面・セッション・CSRF対策) Webサイトを運営していると、「お問い合わせフォーム」はほぼ必須の機能です。訪問者が気軽にコンタクトを取れる窓口であり、ビジネスチャンスにも繋がります。 この記...
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次