![](/img/trans.png)
[英]Google reCAPTCHA V2 checkbox HTML and PHP Contact Form Code
[英]PHP Mailer 6 Contact Form sends message and attachments, but reCaptcha V2 is ignored
我希望我能自己解決這個問題,但我沒有嘗試過。
我已經設法使用 PHPMailer 拼湊了一個聯系表格,並可以選擇添加多個完美的附件。
但是,當我嘗試添加 reCaptcha V2 時,它會被完全忽略,並且無論是否勾選 Captcha,都會提交聯系表單。
我嘗試了許多在線發布的不同方法,但這些方法根本無法提交表單。
有人可以告訴我哪里出錯了:
表單的 HTML 部分:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Contact Us:</title>
<link rel="canonical" href="" />
<link rel="stylesheet" type="text/css" href="css/normalise.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<div class="contact_form_container">
All fields marked with <span class="required">*</span> are required
<form id="form" action="mail-script.php" method="post" enctype="multipart/form-data">
<div class="elem-group">
<label class="form_label">Name <span class="required">*</span></label>
<input class="form-control form-control-name form_field" type="text" name="name" required>
</div>
<div class="elem-group">
<label class="form_label">Company</label>
<input class="form-control form-control-subject form_field" type="text" name="company">
</div>
<div class="elem-group">
<label class="form_label">Email Address <span class="required">*</span></label>
<input class="form-control form-control-email form_field" type="email" name="email" required>
</div>
<div class="elem-group">
<label class="form_label">Phone Number</label>
<input class="form-control form-control-phone form_field" type="tel" name="phone" pattern="\d*">
</div>
<div class="elem-group">
<label class="form_label">Message <span class="required">*</span></label>
<textarea name="message" rows="7" required class="form-control form-control-message form_field">
</textarea>
</div>
<div class="elem-group">
<label class="form_label">Upload Your Files</label>
<input type="file" name="attachment[]" class="form-control" multiple>
</div>
<div class="elem-group">
<label class="form_label"> </label>
<div class="g-recaptcha" data-sitekey="xxxxxx"></div>
</div>
<div class="elem-group">
<label class="form_label cft"> </label>
<button class="btn-primary button" type="submit" value="Send" name="submit" >Send Message</button>
</div>
</form>
</div>
</body>
</html>
PHP
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require './src/Exception.php';
require './src/PHPMailer.php';
require './src/SMTP.php';
class CaptchaTest
{
private $captchaSecretKey = 'XXX';
//call this function and pass in the response value from the form in order to get Google to test the captcha. Will return true or false.
public function testCaptchaResponse($captchaResponse)
{
//generate URL as per Google's documentation
$createGoogleUrl = 'https://www.google.com/recaptcha/api/siteverify?secret='.urlencode($this->captchaSecretKey).'&response='.urlencode($captchaResponse);
//send request to Google and get back the raw JSON response.
$verifyRecaptcha = $this->sendHttpRequest($createGoogleUrl);
//decode the JSON into a PHP array so we can examine individual data items within it
$decodeGoogleResponse = json_decode($verifyRecaptcha,true);
//examine the response from Google and return true/false accordingly.
if($decodeGoogleResponse['success'] == 1) return true;
else return false;
}
//send a HTTP request to the specified URL using cURL
private function sendHttpRequest($url)
{
$ch = curl_init();
$getUrl = $url;
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, $getUrl);
curl_setopt($ch, CURLOPT_TIMEOUT, 80);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}
//check form button and captcha field were submitted
if(isset($_POST['submit'], $_POST['g-recaptcha-response'])) {
//test the captcha
$cTest = new CaptchaTest();
$captchaResult = $cTest->testCaptchaResponse($_POST['g-recaptcha-response']); }
if ($captchaResult == true) {
$mail = new PHPMailer(true);
$mail->SMTPDebug = 0;
$mail->Host = 'in-v3.mailjet.com';
$mail->SMTPAuth = true;
$mail->Username = 'XXX';
$mail->Password = 'XXX';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->setFrom($_POST['email'], $_POST['name']);
$mail->addAddress('XXX@XXX.co.uk');
$mail->addReplyTo($_POST['email'], $_POST['name']);
//Attach multiple files one by one
for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {
$uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
$filename = $_FILES['userfile']['name'][$ct];
if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
$mail->addAttachment($uploadfile, $filename);
}
}
$mail->isHTML(true);
$mail->Subject = 'Website Enquiry';
$mail->Body = "<p>You received an enquiry from:</p>
<b>Name:</b> $_POST[name]<br><br>
<b>Company:</b> $_POST[company]<br><br>
<b>Phone Number:</b> $_POST[phone]<br><br>
<b>E-Mail:</b> $_POST[email]<br><br>
<b>Message:</b> $_POST[message]";
try {
$mail->send();
header('Location: thank.html');
exit('Redirecting you to thank.html');
} catch (Exception $e) {
echo "Your message could not be sent! PHPMailer Error: {$mail->ErrorInfo}";
}
}
else
{
echo "Captcha failed, please try again";
}
?>
提前致謝
目前,您的 PHP 代碼根本不測試驗證碼值。 根據 Google 的文檔,您需要將提交的驗證碼值(在表單的 POST 數據中提供)發送到 Google 的服務器,以便他們對其進行驗證,並就用戶是否通過測試給出是/否響應。 一旦知道這一點,您就可以決定是否繼續發送電子郵件。
我建議將此功能封裝到一個小類中,然后您可以從主代碼流中調用該類來執行檢查。 像這樣的東西:
class ReCaptchaTest
{
private $captchaSecretKey = 'XXXXXXXXX';
//call this function and pass in the response value from the form in order to get Google to test the captcha. Will return true or false.
public function testCaptchaResponse($captchaResponse)
{
//generate URL as per Google's documentation
$createGoogleUrl = 'https://www.google.com/recaptcha/api/siteverify?secret='.urlencode($this->captchaSecretKey).'&response='.urlencode($captchaResponse);
//send request to Google and get back the raw JSON response.
$verifyRecaptcha = $this->sendHttpRequest($createGoogleUrl);
//decode the JSON into a PHP array so we can examine individual data items within it
$decodeGoogleResponse = json_decode($verifyRecaptcha,true);
//examine the response from Google and return true/false accordingly.
if($decodeGoogleResponse['success'] == 1) return true;
else return false;
}
//send a HTTP request to the specified URL using cURL
private function sendHttpRequest($url)
{
$ch = curl_init();
$getUrl = $url;
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, $getUrl);
curl_setopt($ch, CURLOPT_TIMEOUT, 80);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}
然后在您的主代碼中,首先檢查驗證碼值是否已確定提交,然后在嘗試對電子郵件執行任何操作之前運行檢查:
//check form button and captcha field were submitted
if(isset($_POST['submit'], $_POST['g-recaptcha-response'])) {
//test the captcha
$cTest = new CaptchaTest();
$captchaResult = $cTest->testCaptchaResponse($_POST['g-recaptcha-response']);
if ($captchResult == true) {
// go ahead with all your email code here
}
else
{
echo "Captcha failed, please try again";
}
else
{
echo "Please submit the form with all required fields";
}
歸功於本教程的靈感。 使此代碼正常工作還取決於您完成 Google 開發人員帳戶中的所有設置步驟,以便使用 reCaptcha 注冊您的網站(如教程中所示)。
@ADyson 我按照您的建議做了,並在有機會時詳細查看了錯誤。 問題只是證明是“$captchaResult”中缺少“a”。
非常感謝你讓我走到這一步,我非常感謝你的努力和建議,因為我自己不可能做到這一點。
如果它對其他人有幫助,那么工作的 PHP 代碼如下(我還設法標記了在不勾選 reCaptacha 的情況下提交表單的功能會在彈出框中拋出錯誤消息,然后將您發送回完成表格再試一次):
'''
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require './src/Exception.php';
require './src/PHPMailer.php';
require './src/SMTP.php';
class CaptchaTest
{
private $captchaSecretKey = 'XXXXX';
//call this function and pass in the response value from the form in order to get Google to test the captcha. Will return true or false.
public function testCaptchaResponse($captchaResponse)
{
//generate URL as per Google's documentation
$createGoogleUrl = 'https://www.google.com/recaptcha/api/siteverify?secret='.urlencode($this->captchaSecretKey).'&response='.urlencode($captchaResponse);
//send request to Google and get back the raw JSON response.
$verifyRecaptcha = $this->sendHttpRequest($createGoogleUrl);
//decode the JSON into a PHP array so we can examine individual data items within it
$decodeGoogleResponse = json_decode($verifyRecaptcha,true);
//examine the response from Google and return true/false accordingly.
if($decodeGoogleResponse['success'] == 1) return true;
else return false;
}
//send a HTTP request to the specified URL using cURL
private function sendHttpRequest($url)
{
$ch = curl_init();
$getUrl = $url;
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, $getUrl);
curl_setopt($ch, CURLOPT_TIMEOUT, 80);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}
//check form button and captcha field were submitted
if(isset($_POST['submit'], $_POST['g-recaptcha-response'])) {
//test the captcha
$cTest = new CaptchaTest();
$captchaResult = $cTest->testCaptchaResponse($_POST['g-recaptcha-response']); }
if ($captchaResult == true) {
$mail = new PHPMailer(true);
$mail->SMTPDebug = 0;
$mail->Host = 'in-v3.mailjet.com';
$mail->SMTPAuth = true;
$mail->Username = 'XXXXX';
$mail->Password = 'XXXXX';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->setFrom($_POST['email'], $_POST['name']);
$mail->addAddress('XXXXX');
$mail->addReplyTo($_POST['email'], $_POST['name']);
//Attach multiple files one by one
for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {
$uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
$filename = $_FILES['userfile']['name'][$ct];
if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
$mail->addAttachment($uploadfile, $filename);
} }
$mail->isHTML(true);
$mail->Subject = 'Website Enquiry';
$mail->Body = "<p>You received an enquiry from:</p>
<b>Name:</b> $_POST[name]<br><br>
<b>Company:</b> $_POST[company]<br><br>
<b>Phone Number:</b> $_POST[phone]<br><br>
<b>E-Mail:</b> $_POST[email]<br><br>
<b>Message:</b> $_POST[message]";
try {
$mail->send();
header('Location: thank.html');
exit('Redirecting you to thank.html');
} catch (Exception $e) {
echo "Your message could not be sent! PHPMailer Error: {$mail->ErrorInfo}";
}
}
else
{
echo "<script>
alert('Captcha Error!, returning you to the Contact page')
history.back()
</script>";
}
?>
'''
抱歉,如果最終代碼沒有達到應有的優雅水平,我在 PHP 方面仍處於亞虛擬水平......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.