HTMLはクライアントサイドのスクリプト言語なので、メールの送信はできません。当然ながら、HTMLフォームから直接メールを送信することも不可能です。
ただし、HTMLフォームでデータを収集し、サーバーサイドスクリプトやサービスに送信することは可能です。この場合、サーバーサイドスクリプトによりデータが処理され、メールが送信されます。
そこで、このチュートリアルではサーバーサイドスクリプトとHTMLフォームスクリプトの作成、メールの検証、安全なメール送信に必要な全手順を解説していきます。
HTMLフォームから直接メールを送信できない理由
クライアントサイド言語のセキュリティ上の脆弱性をすでにご理解されている場合は、このセクションをスキップしてHTMLフォームの作成方法をご覧ください。
クライアントサイドスクリプト言語であるHTMLコードは、エンドユーザーの端末上で表示され、ブラウザによって解釈されます。
よって、仮にHTMLフォームを使ってサーバーサイドの暗号化なしに直接メールを送信した場合、ページのソースコードを閲覧する者なら誰でもメールアドレスやその他のフォームデータを見られることになります。つまり、この情報は悪意のある者によって悪用され、重大なセキュリティ問題を引き起こす可能性があります。
さらに、HTMLでメール送信できないその他の理由は以下の通りです。
- メール送信ロジックの欠如:HTML単体ではAPI呼び出しやSMTPサーバー接続によるメール送信が不可能です。このプロセスにはサーバーサイドスクリプティングが必ず必要となります。
- リソースの乱用リスク:HTMLにはレート制限機能も存在しないため、短時間でのメール送信数を制御することが困難です。悪用されれば、ホスティングサーバーやメールサービスが提供するリソースを容易に枯渇させる恐れがあります。
フォーム送信からメールを送信するHTMLコードはありますか?
HTMLフォームから直接メールを送信する唯一の方法はmailto:リンクです。このやり方は一見便利かもしれませんが、実は問題があります。
もう少し具体的にお話しすると、mailto:リンクはフォームアクションとして設定可能ですが、それ自体がメールを送信するわけではなく、代わりにメールソフト(例:Microsoft OutlookやApple Mailなど、コンピュータのデフォルトメールソフト)を起動するものです。そして、これはウェブサイトのエンゲージメントやユーザー体験に悪影響を及ぼしてしまう可能性があります。
なぜなら、すべての訪問者がデフォルトのメールソフトを使っているわけではないからです。例えば、ウェブメールのみを使っているユーザーもいます。つまりmailto:リンクを利用すると、使用意図のないソフトウェアのダウンロードをユーザーに強いてしまう可能性があります。さらに、ウェブサイトとメールアプリの切り替えを強制するのは、ユーザーフレンドリーとはいえないでしょう。ただしこれは、ブラウザが当該機能をサポートし、メールクライアントが開かれる場合の話です。
加えて、mailto:の機能はかなり制限されていて、添付ファイルの追加やメールの書式設定は制御できません。
メールの件名や本文を事前に入力してポップアップされるメールクライアントウィンドウに表示させることは可能です。しかしこの場合、URLが長くなりすぎる可能性があり、ブラウザにURLの長さ制限がある際はmailto:が正しく処理されなかったり、誤って表示されたりする恐れがあります。
それでも試してみたい方向けに、mailto:の簡単な例を以下に示します。
<a href="mailto:masteryoda@starwars.com">スターウォーズが大好きです</a>
Cc、Bcc、件名、メール本文を追加した場合の表示例:
<a href="mailto:masteryoda@starwars.com? cc=skywalker@starwars.com& bcc=leia@starwars.com& subject=フォースと%20共に%20あれ&body=フォースが%20我々と%20共に%20あらんことを%20%3A%0D%0A%0D%0A敬具%2C%0D%0A満足している%20お客さんより">スターウォーズが大好きです</a>
JavaScriptでHTMLフォームを使ってメールを送信できますか?
いいえ、できません。JavaScriptはクライアントサイドのスクリプトなので、JavaScriptを使ってメールを送信すると、HTMLと同様の脆弱性の問題が発生してしまいます。
ただし、メールアドレスなどのフォームフィールドの検証にはJavaScriptを使用できます。その後、サーバーサイド言語(最も一般的なのはPHP)を介してフォーム送信を実行することも可能です。この組み合わせの使い方は以下で解説します。
HTMLフォームの作り方
メール送信スクリプトを作成する前に、まずはシンプルなHTMLコンタクトフォームを作成してみましょう。ここでは簡単な例をご紹介するので、CSSスタイルは使いません。このフォームは幼児の落書きのようなものかもしれませんが、ピカソ級のコーディングを目指しているわけではないのでご理解ください。
シンプルなHTMLフォームのコードは以下のようなものです。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>お問い合わせフォーム</title>
</head>
<body>
<h2>お問い合わせ</h2>
<label for="name">お名前:</label>
<input type="text" id="name" name="name" required>
<br>
<label for="email">メールアドレス:</label>
<input type="email" id="email" name="email" required>
<br>
<label for="message">メッセージ:</label>
<textarea id="message" name="message" required></textarea>
<br>
<button type="submit">送信</button>
</form>
</body>
</html>
そしてユーザーには以下のように表示されます:

PHPのHTMLフォームからメールを送るやり方
PHPのHTMLフォームからメールを送るには、フォーム入力の検証も必要です。これにより、masteryoda@starwarsやmasteryoda.starwars.comのような無効なアドレスを回避できます。
検証には、HTML5の組み込み検証とJavaScriptのvalidate.jsという2つのやり方があります。
HTML5とPHPを使ったメール送信の検証
HTML5はHTMLの最新バージョンで、required、pattern、typeなどの属性を使ってフォーム入力を検証してくれます。したがって、クライアントサイド検証を実行するために使用できます。
以下のコードはHTML5検証機能を備えたHTMLフォームの例です。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>お問い合わせフォーム</title>
</head>
<body>
<form action="send_email.php" method="post">
<label for="firstName">お名前:</label>
<input type="text" id="firstName" name="firstName" required>
<br>
<label for="email">メールアドレス:</label>
<input type="email" id="email" name="email" required>
<br>
<label for="message">メッセージ:</label>
<textarea id="message" name="message" required></textarea>
<br>
<input type="submit" value="送信">
</form>
</body>
</html>
このスクリプトではフォームメソッドがPOSTで定義されており、これはサーバーにPOSTリクエストを送信することを意味しています。required属性を使うため、名前、メールアドレス、メール本文などのフィールドは必須入力項目です。これらのフィールドのいずれかが空の状態で「送信」をクリックすると、「このフィールドを入力してください」というメッセージが表示されます。

input type="email" は入力されたメールアドレスが有効な形式かどうかをチェックし、form action="send_email.php" はリクエストを処理してメールを送信するPHPスクリプトを指します。
次にサーバーサイド検証を追加します。以下のコードは名前・メールアドレス・メッセージ欄が空欄でないかを確認してくれます。メールアドレス欄に入力がある場合、その有効性が検証されます。$errors配列には、無効または未入力の入力項目に対応するエラーメッセージが格納されます。
<?php
$errors = [];
if (!empty($_POST)) {
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
if (empty($name)) {
$errors[] = '名前が空です';
}
if (empty($email)) {
$errors[] = 'メールアドレスが空です';
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'メールアドレスが無効です';
}
if (empty($message)) {
$errors[] = 'メッセージが空です';
}
}
この段階で、PHPでメール送信スクリプトの記述を開始できます。
注記: PHPはメール送信にmail()関数を使用し、PHPが動作するサーバー上で設定されたローカルメールサーバーを利用します。これは安全なメール送信方法ではないため、使用は推奨しません。より安全で信頼性の高い選択肢としてPHPMailerがあるので、次のセクションで詳しく説明いたします。
それでは、HTMLコードで指定された名前で新しいPHPファイルを作成します。今回の例の場合、send_email.phpとなります。リクエストがPOSTの場合、名前、メールアドレス、メッセージなどのフォームデータが取得され、その後、フォームフィールドの検証が行われます。
すべてが正しい場合、指定された受信者アドレスにメールが送信されます。リクエストがPOSTでない場合、「403 Forbiddenエラー」が表示されます。
<?php
$errors = [];
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// POSTデータを取得
$name = isset($_POST['name']) ? strip_tags(trim($_POST['name'])) : '';
$email = isset($_POST['email']) ? trim($_POST['email']) : '';
$message = isset($_POST['message']) ? strip_tags(trim($_POST['message'])) : '';
// フォームフィールドの検証
if (empty($name)) {
$errors[] = '名前が空です';
}
if (empty($email)) {
$errors[] = 'メールアドレスが空です';
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'メールアドレスが無効です';
}
if (empty($message)) {
$errors[] = 'メッセージが空です';
}
// エラーがない場合、メールを送信
if (empty($errors)) {
// 受信者メールアドレス(ご自身のアドレスに置き換えてください)
$recipient = "recipient@example.com";
// 追加ヘッダー
$headers = "From: $name <$email>";
// メール送信
if (mail($recipient, $message, $headers)) {
echo "メール送信成功!";
} else {
echo "メール送信に失敗しました。後ほど再度お試しください。";
}
} else {
// エラーを表示
echo "フォームに以下のエラーが含まれています:<br>";
foreach ($errors as $error) {
echo "- $error<br>";
}
}
} else {
// POSTリクエストではないため、403 Forbiddenエラーを表示
header("HTTP/1.1 403 Forbidden");
echo "このページへのアクセスは許可されていません。";
}
?>
PHPでメールを送るやり方については、こちらのブログ記事またはこちらの動画をご覧ください。
WordPressやDrupalでお問い合わせページを作成するには、PHPコンタクトフォームを利用できます。ただし、コーディングを避けたい場合は、複数のフォームビルダープラグインが利用可能です。
PHPMailerを使ってHTMLウェブフォームからのメール送信
PHPMailerはSMTPサーバー経由でメールを送信し、最新のセキュリティ基準に準拠しているため、PHPのmail関数に代わる安全な選択肢です。以下のコード行を使ってComposer経由でインストールできます。
composer require phpmailer/phpmailer
メールの送信にはSMTPサーバーも必要です。この例では、高い配信到達率を達成するよう設計されたメールインフラストラクチャであるMailtrapのメール配信API/SMTPを使います。なおこのツールには、すぐ簡単にセットアップできるメール配信 APIとSMTPサービスが搭載されています。
SMTP認証情報にアクセスするにはhttps://mailtrap.io/ja/にアクセスし、アカウントを作成します。

次に「送信ドメイン」に移動し、送信ドメインを追加します。その後、以下の動画の手順に従って検証します。
設定が完了したら「API」と「SMTP」タブに移動し、使用する送信ストリーム(トランザクショナルまたはバルク(一斉送信メール))を選択し、SMTPまたはAPIを選択します。

SMTP認証情報をメモし、PHPMailerコードの作成に戻ります。
上記のHTMLページに対応するPHPMailerスクリプトは以下のようになります。
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$errors = [];
$errorMessage = ' ';
$successMessage = ' ';
echo 'sending ...';
if (!empty($_POST))
{
$name = $_POST['firstName'];
$email = $_POST['email'];
$message = $_POST['message'];
if (empty($name)) {
$errors[] = '名前が空です';
}
if (empty($email)) {
$errors[] = 'メールアドレスが空です';
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'メールアドレスが無効です';
}
if (empty($message)) {
$errors[] = 'メッセージが空です';
}
if (!empty($errors)) {
$allErrors = join ('<br/>', $errors);
$errorMessage = "<p style='color: red; '>{$allErrors}</p>";
} else {
$fromEmail = 'アドレス例@サンプル.com';
$emailSubject = 'お問い合わせフォームからの新規メール';
// 新しいPHPMailerインスタンスを作成
$mail = new PHPMailer(exceptions: true);
try {
// PHPMailerインスタンスの設定
$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'api';
$mail->Password = 'smtpの_パスワード';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
// メッセージの送信者、受信者、件名、本文を設定
$mail->setFrom($email);
$mail->addAddress($email);
$mail->setFrom($fromEmail);
$mail->Subject = $emailSubject;
$mail->isHTML( isHtml: true);
$mail->Body = "<p>名前: {$name}</p><p>メールアドレス: {$email}</p><p>メッセージ: {$message}</p>";
// メッセージを送信
$mail->send () ;
$successMessage = "<p style='color: green; '>お問い合わせありがとうございます :)</p>";
} catch (Exception $e) {
$errorMessage = "<p style='color: red; '>問題が発生しました。後ほど再度お試しください</p>";
echo $errorMessage;
}
}
}
?>
なお、プレースホルダーを実際の変数で置き換えることをどうぞお忘れなく。
PHPMailerの特性についてさらに深くお知りになりたい場合は、このトピックについてのブログ記事をご覧ください。
さらに、メール配信API/SMTPで初めてのメール送信を行う際は、実用的な分析機能を活用してパフォーマンスを追跡することをオススメします。開封率・クリック率・バウンス率の統計を確認して、お使いのインフラをしっかり管理しましょう。

JavaScriptとPHPコードを使ったメールの検証・送信
HTMLメールフォームの入力内容をJavaScriptで検証するにはvalidate.jsのインストールが必要なので、CDNからライブラリを追加します。
<script src="//cdnjs.cloudflare.com/ajax/libs/validate.js/0.13.1/validate.min.js"></script>
検証スクリプトは次のようになります。
<script>
const constraints = {
name: {
presence: { allowEmpty: false }
},
email: {
presence: { allowEmpty: false },
email: true
},
message: {
presence: { allowEmpty: false }
}
};
const form = document.getElementById('contact-form');
form.addEventListener('submit', function (event) {
const formValues = {
name: form.elements.name.value,
email: form.elements.email.value,
message: form.elements.message.value
};
const errors = validate(formValues, constraints);
if (errors) {
event.preventDefault();
const errorMessage = Object
.values(errors)
.map(function (fieldValues) { return fieldValues.join(', ')})
.join("\n");
alert(errorMessage);
}
}, false);
</script>
上記のコードは、フォームフィールドを検証するためのルールがある制約オブジェクトを定義しています。名前、メールアドレス、メッセージのフィールドは空欄にできず、メールアドレスフィールドに有効な値が入力されている必要があります。
フォーム定数にはdocument.getElementByIdを使い、contact-formというIDを持つHTMLフォーム要素が割り当てられます。
フォーム送信時にトリガーされる関数は、フィールドデータを抽出してformValuesオブジェクトに格納します。その後、validate()関数でformValuesを検証します。検証エラーがある場合、event.preventDefault()でフォーム送信を阻止します。
エラーメッセージは単一のerrorMessage文字列にまとめられ、alert()関数で表示されます。
バックエンドの検証は、前の例と同じになります。
以下に、PHPとJavaScriptによる検証処理、およびHTML形式のメールフォーム本体を含む完全なコードサンプルを示します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>お問い合わせフォーム送信</title>
</head>
<body>
<form method="post" id="contact-form">
<h2>お問い合わせ</h2>
<?php
$errorMessage = ''; // $errorMessage を定義
echo(!empty($errorMessage) ? $errorMessage : '');
?>
<p>
<label>お名前:</label>
<input name="name" type="text"/>
</p>
<p>
<label>メールアドレス:</label>
<input style="cursor: pointer;" name="email" type="text"/>
</p>
<p>
<label>メッセージ:</label>
<textarea name="message"></textarea>
</p>
<p>
<input type="submit" value="送信"/>
</p>
</form>
<script src="//cdnjs.cloudflare.com/ajax/libs/validate.js/0.13.1/validate.min.js"></script>
<script>
const constraints = {
name: {
presence: { allowEmpty: false }
},
email: {
presence: { allowEmpty: false },
email: true
},
message: {
presence: { allowEmpty: false }
}
};
const form = document.getElementById('contact-form');
form.addEventListener('submit', function(event) {
const formValues = {
name: form.elements.name.value,
email: form.elements.email.value,
message: form.elements.message.value
};
const errors = validate(formValues, constraints);
if (errors) {
event.preventDefault();
const errorMessage = Object.values(errors)
.map(function(fieldValues) {
return fieldValues.join(', ');
})
.join("\n");
alert(errorMessage);
}
}, false);
</script>
</body>
</html>
PHPMailerを使用したHTMLフォームからのメール送信
PHPをPHPMailerに置き換える作業を再度行いますが、今回はreCAPTCHAも追加します。
Google reCAPTCHAのページにアクセスし、バージョンを選択します。コード全体を書き直してフロントエンドから手動でreCAPTCHAをトリガーしたい場合を除き、「Challenge (v2)」のご利用をお勧めします。これはバックエンドで処理し、フォームと共に送信できます。
Googleは2種類のreCAPTCHA v2を提供しています。
- 「私はロボットではありません」チェックボックス。リクエストを「私はロボットではありません」のチェックボックスで検証するタイプ
- バックグラウンドでリクエストを検証する「目に見えないreCAPTCHAバッジ」
今回は非表示バッジを選択します。「Submit」ボタンをクリックすると「Site Key」と「Secret Key」が表示されます。以下のコードにこれらの値を挿入する必要があるため、両方とも書き留めておきます。
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$errors = [];
$errorMessage = '';
$successMessage = '';
$siteKey = 'RECAPTCHA_サイトの_鍵';
$secret = 'RECAPTCHAの_秘密の_鍵';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = sanitizeInput ($_POST['name']);
$email = sanitizeInput ($_POST['email']);
$message = sanitizeInput ($_POST ['message']);
$recaptchaResponse = sanitizeInput ($_POST['g-recaptcha-response']);
$recaptchaUrl = "https://www.google.com/recaptcha/api/siteverify?secret={$secret]&response={$recaptchaResponse]";
$verify = json_decode(file_get_contents($recaptchaUrl));
if (!$verify->success) {
$errors [ ] = 'Recaptchaに失敗しました';
}
if (empty ($name)) {
$errors [ ] = '名前が空です';
}
if (empty ($email)) {
$errors [ ] = 'メールアドレスが空です';
} else if (!filter_var($email, filter: FILTER_VALIDATE_EMAIL)) {
$errors [ ] = 'メールアドレスが無効です';
}
if (empty ($message)) {
$errors [ ] = 'メッセージが空です';
}
if (!empty ($errors)) {
$allErrors = join ( separator: '<br/>', $errors);
$errorMessage = "<p style='color: red; '>{$allErrors}</p>";
} else {
$toEmail = 'アドレス例@サンプル.com';
$emailSubject = 'お問い合わせフォームからの新規メール';
// 新しいPHPMailerインスタンスを作成
$mail = new PHPMailer (exceptions: true);
try {
// PHPMailerインスタンスの設定
$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'api';
$mail->Password = 'smtpの_パスワード';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
// メッセージの送信者、受信者、件名、本文を設定
$mail->setFrom($email);
$mail->addAddress($toEmail);
$mail->Subject = $emailSubject;
$mail->isHTML( isHtml: true);
$mail->Body = "<p>名前: {$name}</p><p>メールアドレス: {$email}</p><p>メッセージ: {$message}</p>;
// メッセージを送信
$mail->send () ;
$successMessage = "<p style='color: green; '>お問い合わせありがとうございます :)</p>";
} catch (Exception $e) {
$errorMessage = "<p style='color: red; '>問題が発生しました。後ほど再度お試しください</p>";
}
}
}
function sanitizeInput($input) {
$input = trim($input);
$input = stripslashes($input);
$input = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
return $input;
}
?>
<html>
<body>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<form action="/" method="post" id="contact-form">
<h2>Contact us</h2>
<?php echo (!empty($errorMessage) ? $errorMessage : ''); ?>
<?php echo (!empty($successMessage) ? $successMessage : ''); ?>
<p>
<label>お名前:</label>
<input name="name" type="text" required />
</p>
<p>
<label>メールアドレス:</label>
<input style="..." name="email" type="email" required />
</p>
<p>
<label>メッセージ:</label>
<textarea name="message" required></textarea>
</p>
<p>
<button class="g-recaptcha" type="submit" data-sitekey="<?php echo $siteKey ?>" data-callback="onRecaptchaSuccess">
送信
</button>
</p>
</form>
<script>
function onRecaptchaSuccess() {
document.getElementById('contact-form').submit();
}
</script>
</body>
</html>
このスクリプトはreCAPTCHAバッジを組み込み、サーバーサイド検証を実行し、SMTPサーバー経由でメールを送信します。Host、SMTPAuth、Username、Password、SMTPSecure、Portなどのプロパティには、ご自身のMailtrap認証情報をご入力ください。
添付ファイル付きHTMLフォームメールの送信方法
添付ファイル付きのHTMLフォームメールを送信することも可能です。その場合、よりシンプルなPHPMailerの使用をお勧めします。
本文プロパティの後に$mail->AddAttachment()メソッドを使用するだけで終わりです。
$mail->AddAttachment($_FILES["attachment"]["tmp_name"], $_FILES["attachment"]["name"]);
まとめ
これでHTMLフォームからメール送信する際のすべての手順をご理解いただけたでしょうか。もうお問い合わせフォームも怖くありません。見た目がシンプルなものでもリニューアル済み✨のものでも、PHPMailer、reCAPTCHA、JavaScript検証を活用すれば安全にメールを送信できます。
他のプログラミング言語でお問い合わせフォームを作成したい場合は、当社のYouTubeチャンネルをぜひご覧ください。お問い合わせフォームについて複数のチュートリアルを公開しております。
- PHPコンタクトフォーム
- Vue.jsコンタクトフォーム
- JavaScriptコンタクトフォーム
- Ruby on Rails コンタクトフォーム
- Django コンタクトフォーム
- Flask コンタクトフォーム
なお、HTMLフォームをマスターするには、以下のブログ記事もご参考にしてください。