- 正常系をまず作成
- 異常系を考える、テストする、キリがない
- マストな異常系をルール化する(経験がものをいう)
- 失敗する前提で記述
- 失敗のログがでるように
- 時間をおいてお試してください
- SQLインジェクション、CSRF
→参考:体系的に学ぶ 安全なWebアプリケーションの作り方 第2版[固定版] 脆弱性が生まれる原理と対策の実践
Contents
POSTリクエストはContent-Typeはapplication/json
POSTリクエストを使うとき、サーバーにデータを送信する形式を示すために「Content-Type」というヘッダーを設定する
application/json
- JSON形式でデータを送信するときに使います。
- 例えば、フォームデータをJavaScriptでオブジェクトにして送信したい場合に利用します。
正常系を完成させる
フロントエンドからのフォームデータ送信
script.js
の sendMail
関数で、axios
を使ってフォームデータをsendMailer.php
に送信しています(script)。まず、データが正しくサーバーに送信されているかを確認します。
PHP側でのデータ受信とレスポンス
sendMailer.php
で、送信されたデータを受け取り、PHPMailerを用いてメールを送信する処理を追加します。現状のコードでは、PHPMailerの処理が未実装ですので、これを追加します。
フロントエンドでの成功メッセージの表示
メール送信が正常に完了した場合、フロントエンドで成功メッセージを表示させます。すでに sendMail
関数内でレスポンスに基づく処理が行われているため、サーバーから成功レスポンスが返ってきた際に次のページにリダイレクトするか、成功メッセージを表示するように設定します。
memo
デフォルトでは Content-Type
が application/json
になりますが、PHP で $_POST
を使用してデータを取得するには application/x-www-form-urlencoded
形式で送信する必要がある
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>フォーム送信</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="form_wrap">
<form class="form" onSubmit="handleSubmit(event)" name="cta_form">
<p class="form_title">form</p>
<div class="form_area">
<!-- メールアドレス入力欄 -->
<input class="form_input" type="email" name="email" placeholder="メールアドレス" required>
<div class="err" id="emailError"></div>
<!-- 電話番号入力欄 -->
<input class="form_input" type="tel" maxlength="11" name="tel" placeholder="例) 09012345678" required>
<div class="err" id="telError"></div>
<!-- 送信ボタン -->
<button class="submit" type="submit">送信</button>
</div>
</form>
</div>
<div id="formMessage" class="form_message"></div>
<!-- JavaScriptの読み込みをbodyの最後に移動 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="script.js"></script>
</body>
</html>
$(document).ready(function () {
async function sendMail(formData) {
try {
const url = "https://siennahare23.sakura.ne.jp/1104_tokuform/sendMailer.php";
console.log("送信データ:", formData);
const res = await axios.post(url, JSON.stringify(formData), {
headers: {
"Content-Type": "application/json",
},
});
const json = res.data;
console.log("サーバーからのレスポンス:", json);
return { success: json.status === "success", data: json };
} catch (error) {
console.error("PHPへの送信エラー:", error);
return { success: false, error: error };
}
}
window.handleSubmit = async function (event) {
event.preventDefault();
const form = event.currentTarget;
// 入力要素の取得
const emailInput = form.querySelector('input[name="email"]');
const telInput = form.querySelector('input[name="tel"]');
const emailValue = emailInput.value;
const telValue = telInput.value;
// 電話番号とメールアドレスのバリデーション
if (telValue.length !== 11 || !/^\d{11}$/.test(telValue)) {
document.getElementById("telError").innerText = "11桁の電話番号を入力してください";
return;
} else {
document.getElementById("telError").innerText = "";
}
if (!/^[\w\.-]+@[\w\.-]+\.\w+$/.test(emailValue)) {
document.getElementById("emailError").innerText = "有効なメールアドレスを入力してください";
return;
} else {
document.getElementById("emailError").innerText = "";
}
// フォームデータの収集
const data = new FormData(form);
const formData = Object.fromEntries(data.entries());
const result = await sendMail(formData);
// メッセージ表示要素を取得
const messageDiv = document.getElementById("formMessage");
// 成功・失敗のメッセージを表示
if (result.success) {
messageDiv.innerText = result.data.message || "メールが正常に送信されました";
messageDiv.style.color = "green";
} else {
messageDiv.innerText = result.data.message || "送信エラーが発生しました。再度お試しください。";
messageDiv.style.color = "red";
}
};
});
<?php
// 設定ファイルの読み込み
require_once '/home/siennahare23/config/config.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// JSON データの取得と解析
$input = file_get_contents('php://input');
$data = json_decode($input, true);
// 入力データの取得
$email = filter_var($data['email'], FILTER_SANITIZE_EMAIL);
$tel = filter_var($data['tel'], FILTER_SANITIZE_STRING);
// デバッグ情報の出力
// echo '取得したメールアドレス: ' . htmlspecialchars($email) . '<br>';
// echo '取得した電話番号: ' . htmlspecialchars($tel) . '<br>';
// メールアドレスの検証
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo '無効なメールアドレスです: ' . htmlspecialchars($email);
exit;
}
// 電話番号の検証
if (!preg_match('/^\d{11}$/', $tel)) {
echo '無効な電話番号です: ' . htmlspecialchars($tel);
exit;
}
// デバッグ情報の出力
// echo '送信先メールアドレス: ' . htmlspecialchars($email) . '<br>';
// echo '送信先電話番号: ' . htmlspecialchars($tel) . '<br>';
$mail = new PHPMailer(true);
try {
// SMTP設定
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USER;
$mail->Password = SMTP_PASS;
$mail->SMTPSecure = SMTP_SECURE;
$mail->Port = SMTP_PORT;
// エンコーディングの設定
$mail->CharSet = 'UTF-8';
$mail->Encoding = 'base64';
// 送信者と受信者の設定
$mail->setFrom(SMTP_USER, 'Mailer'); // 送信者
$mail->addAddress($email); // 受信者
// メール内容の設定
$mail->isHTML(true);
$mail->Subject = 'フォーム送信内容';
$mail->Body = 'メールアドレス: ' . htmlspecialchars($email) . '<br>電話番号: ' . htmlspecialchars($tel);
$mail->AltBody = 'メールアドレス: ' . htmlspecialchars($email) . "\n電話番号: " . htmlspecialchars($tel);
// メール送信
$mail->send();
echo json_encode(['status' => 'success', 'message' => 'メッセージが送信されました']);
} catch (Exception $e) {
echo json_encode(['status' => 'error', 'message' => "メッセージを送信できませんでした。エラー: {$mail->ErrorInfo}"]);
}
} else {
echo json_encode(['status' => 'error', 'message' => 'POSTメソッドで送信してください。']);
}
?>