前提・実現したいこと
AjaxとPHPを使って自動返信機能付きの問い合わせフォームの実装
発生している問題・エラーメッセージ
入力フォームで入力されたメールアドレスが文字化けしてPHPに渡されてしまいます。
具体的には「hoge.muni@gmail.com」 → 「hoge_muni@gmail_com」 の様にドットがアンダーバーに変換されてしまいます。
JavaScriptでJSON形式に変換するまでは問題も無さそうなのですが、PHPに渡すと文字化けします。
該当のソースコード
html
1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4<meta charset="utf-8"> 5<title>AjaxMailForm</title> 6<link href="hello_ajax.css" rel="stylesheet" type="text/css"> 7</head> 8<body> 9 <h1>Hello_ajax</h1> 10 11 <table> 12 <tr> 13 <th>商品配達先ご記入欄<span class="required">*は必須項目</span></th> 14 </tr> 15 <tr> 16 <th><span class="required">*</span>氏名</th> 17 <td> 18 <label>姓:</label><input type="text" id="familyName" name="requiredItem" placeholder="例)牟尼"> 19 <label>名:</label><input type="text" id="firstName" name="requiredItem" placeholder="例)歩花"> 20 </td> 21 </tr> 22 <tr> 23 <th><span class="required">*</span>カタカナ</th> 24 <td> 25 <label>姓:</label><input type="text" id="familyKana" name="requiredItem" placeholder="例)ムニ"> 26 <label>名:</label><input type="text" id="firstKana" name="requiredItem" placeholder="例)ホゲ"> 27 </td> 28 </tr> 29 <tr> 30 <th><span class="required">*</span>メールアドレス</th> 31 <td> 32 <input type="text" id="email" size="30" placeholder="例)muni-hoge123@〇〇.co.jp"> 33 </td> 34 </tr> 35 <tr> 36 <th>配達希望時間</th> 37 <td> 38 <label>指定なし:</label><input name="deliveryTime" type="radio" value="指定なし"> 39 <label>午前中:</label><input name="deliveryTime" type="radio" value="午前中"> 40 <label>12~14時:</label><input name="deliveryTime" type="radio" value="12-14時"> 41 <label>14~16時:</label><input name="deliveryTime" type="radio" value="14-16時"> 42 <label>16~18時:</label><input name="deliveryTime" type="radio" value="16-18時"> 43 <label>18~20時:</label><input name="deliveryTime" type="radio" value="18-20時"> 44 <label>20~21時:</label><input name="deliveryTime" type="radio" value="20-21時"> 45 </td> 46 </tr> 47 </table> 48 49 <button id="modalBtn">入力内容を確認</button> 50 <div id="mask"> 51 <div id="result"> 52 <div class="result-inner"> 53 <div id="checkArea"> 54 55 </div> 56 <div class="checkBtnArea"> 57 <button id="backBtn">入力画面に戻る</button> 58 <form><input id="sendBtn" type="button" name="submit" value="送信"></form> 59 </div> 60 </div> 61 62 </div> 63 </div> 64 65<script src="hello_ajax.js"></script> 66</body> 67</html> 68
JavaScript
1 2document.addEventListener('DOMContentLoaded', function() { 3 4 // ラジオボタン取得の関数 5 var getRadioValue = function(name) { 6 var result = ''; 7 var elments = document.getElementsByName(name); 8 for (var i = 0, len = elments.length; i < len; i++) { 9 var element = elments.item(i); 10 if (element.checked) { 11 result = element.value; 12 break; 13 } 14 } 15 return result; 16 }; 17 18 var mask = document.getElementById('mask'); 19 var checkArea = document.getElementById('checkArea'); 20 21 document.getElementById('modalBtn').addEventListener('click', function() { 22 23 // 必須項目の入力チェック 24 function requiredCheck(init) { 25 var requiredItems = document.getElementsByName('requiredItem'); 26 var num = init; 27 for (var i = 0, len = requiredItems.length; i < len; i++) { 28 var requiredItem = requiredItems.item(i); 29 //再度チェック時の初期化 30 requiredItem.classList.remove('notEntered'); 31 if (requiredItem.type == 'text' || requiredItem.type == 'textarea') { 32 if (requiredItem.value == '' ) { //inputが空の場合 33 requiredItem.classList.add('notEntered'); 34 num++; 35 } 36 } 37 } 38 //クロージャを利用してローカル変数のnumを参照可能にする 39 return function() { 40 return num; 41 } 42 } 43 //未入力の個数を取得 44 var requiredNum = requiredCheck(0); 45 46 // メール正規表現チェック関数 47 function checkRegEmail(str) { 48 strValue = str.value 49 var mailCheck = new RegExp('[a-z0-9._-]+@+[a-z0-9.]+[^.]$', 'gi'); 50 if (strValue.match(mailCheck)) { //マッチした場合 51 console.log("メールアドレスの形式は正しいです"); 52 return true; 53 } else { //マッチしなかった場合 54 str.classList.add('notMatch'); 55 return false; 56 } 57 } 58 // メールチェック関数の実行 59 var resultEmail = checkRegEmail(document.getElementById('email')); 60 61 // 必須項目が全て入力 & メール正規表現が確認出来た場合 62 if (requiredNum() == 0 && resultEmail) { 63 mask.style.display = 'block'; 64 //formの値を取得 65 var familyName = document.getElementById('familyName').value; //氏名(姓) 66 var firstName = document.getElementById('firstName').value; //氏名(名) 67 var familyKana = document.getElementById('familyKana').value; //カナ(姓) 68 var firstKana = document.getElementById('firstKana').value; //カナ(名) 69 var email = document.getElementById('email').value; //メールアドレス 70 var deliveryTime = getRadioValue('deliveryTime'); //配達希望時間 71 console.log(deliveryTime); 72 //確認用のテキストノードを生成 73 document.createElement('list'); 74 var checkfamilyName = document.createTextNode(familyName); 75 //ノードを挿入 76 checkArea.appendChild(checkfamilyName); 77 78 //btnクリックで確認イベント発火 79 document.getElementById('sendBtn').addEventListener('click', function() { 80 //非同期通信の処理 81 var xhr = new XMLHttpRequest(); 82 xhr.onreadystatechange = function() { 83 if(xhr.readyState === 4) { //通信完了時の処理 84 if(xhr.status === 200) { //通信成功時の処理 85 checkArea.textContent = xhr.responseText; 86 } else { //通信が失敗した時 87 checkArea.textContent = 'サーバーエラーが発生しました。'; 88 } 89 } else { //通信が完了する前 90 checkArea.textContent = '通信中...'; 91 } 92 }; 93 //JSONデータとして格納 94 var sendData = JSON.stringify({ 95 'familyName' : familyName, 96 'firstName' : firstName, 97 'familyKana' : familyKana, 98 'firstKana' : firstKana, 99 'email' : email, 100 101 'deliveryTime' : deliveryTime 102 }); 103 //POSTメソッドでデータ送信 104 xhr.open('POST', 'hello_ajax.php', true); 105 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); 106 xhr.send(sendData); 107 console.log(email) 108 }, false); 109 } 110 }, false); 111 112 //backBtnクリックで入力確認画面へ戻る 113 document.getElementById('backBtn').addEventListener('click', function() { 114 mask.style.display = 'none'; 115 }, false); 116}, false); 117 118
PHP
1<?php 2 3// 日本語対応 4mb_language("ja"); 5mb_internal_encoding("UTF-8"); 6 7// タイムゾーンの定義 8date_default_timezone_set('Asia/Tokyo'); 9 10// JSONの取扱宣言 11header( "Content-Type: application/json; charset=utf-8" ) ; 12 13//エラー表示設定 14error_reporting(E_ALL); 15ini_set('display_errors',1); 16 17 18 19//POSTで受けとったJSONデータをオブジェクトデータに変更 20$i = 0; 21$arr = []; 22foreach($_POST as $key => $value) { 23 $i++; 24 $obj = json_decode($key); 25} 26function h($value) { 27 return htmlspecialchars($value,ENT_QUOTES,'UTF-8'); 28} 29 30//各フォームの変数定義 31$familyName = h($obj->familyName); //氏名(姓) 32$firstName = h($obj->firstName); //氏名(名) 33$familyKana = h($obj->familyKana); //カナ(姓) 34$firstKana = h($obj->firstKana); //カナ(名) 35$email = h($obj->email); //メールアドレス(自動返信) 36 37$deliveryTime = h($obj->deliveryTime); //配達希望時間 38 39 40 41$name = "お客様名前"; 42 43 44$contentbox = '本文'; 45 46 47$fromEmail = "Web管理者のメールアドレス"; 48$fromName = "Web管理者の名前"; 49 50 51 52//自動返信メールの内容 53$subject = "この度はお問い合わせいただきありがとうございました。"; 54 55//メール本文 56$body = <<< EOM 57{$name} 様 58 59お問い合わせいただきありがとうございます。 60以下の内容で受け付けいたしました。 61 62=================================================== 63 64お名前:{$familyName} {$firstName} 65カタカナ:{$familyKana} {$firstKana} 66メール:$email 67 68配達希望時間:{$deliveryTime} 69 70お問い合わせ内容:{$contentbox} 71 72=================================================== 73 74担当者よりご連絡いたしますので今しばらくお待ちくださいませ。 75 76EOM; 77 78 79//Web管理者への確認メール 80$subbody = <<< EOM 81 82Webサイトからお問い合わせいただきました。 83以下に内容を記載しています。 84 85=================================================== 86【 お名前 】 87{$familyName} {$firstName} 88【 カタカナ 】 89{$familyKana} {$firstKana} 90 91【 メール 】 92 93【 配達希望時間 】 94{$deliveryTime} 95 96【 お問い合わせ内容 】 97{$contentbox} 98=================================================== 99EOM; 100 101 102//ヘッダー情報の設定(自動返信) 103$header = ''; 104$header .= "Content-Type: text/plain \r\n"; 105$header .= "Return-Path: " . $fromEmail . " \r\n"; 106$header .= "From: " . mb_encode_mimeheader($fromName) ."<{$fromEmail}> \r\n"; 107$header .= "Sender: " . $fromName ." \r\n"; 108$header .= "Reply-To: " . $fromEmail . " \r\n"; 109$header .= "Organization: " . $fromEmail . " \r\n"; 110$header .= "X-Sender: " . $fromEmail . " \r\n"; 111$header .= "X-Priority: 3 \r\n"; 112$param = "-f" . $fromEmail; 113 114//ヘッダー情報の設定(Web管理者) 115$subheader = ''; 116$subheader .= "Content-Type: text/plain \r\n"; 117$subheader .= "Return-Path: " . $email . " \r\n"; 118$subheader .= "From: " . mb_encode_mimeheader($name) ."<{$email}> \r\n"; 119$subheader .= "Sender: " . $name ." \r\n"; 120$subheader .= "Reply-To: " . $email . " \r\n"; 121$subheader .= "Organization: " . $email . " \r\n"; 122$subheader .= "X-Sender: " . $email . " \r\n"; 123$subheader .= "X-Priority: 3 \r\n"; 124$subparam = "-f" . $email; 125 126//送信者へメール送信(自動返信) 127mb_send_mail($email, $subject, $body, $header, $param); 128 129//メール送信(Web管理者) 130mb_send_mail($fromEmail, $subject, $subbody, $subheader, $subparam); 131 132 133// 完了画面に表示される内容 134print($body); 135 136 137 138 139 140 141?> 142
試したこと
JavaScript
1xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
この部分をJSONで渡すので、「application/json」にしてみたり
JavaScript
1xhr.setRequestHeader('Content-Type','application/json; charset=UTF-8');
PHP側で
json_decode()やらjson_encode()など色々試してみみましたが何故か文字化けしてしまいます。困り果てております。
補足情報(FW/ツールのバージョンなど)
環境
レンタルサーバーで PHP 7.3.9 (CGI版) です。
不完全な部分が多々あると思いますが、どうぞよろしくお願いします。
回答1件
あなたの回答
tips
プレビュー