gpt4 book ai didi

javascript - 在PHPMailer上成功/失败的不同行为

转载 作者:行者123 更新时间:2023-12-01 02:38:38 25 4
gpt4 key购买 nike

我有一个PHPMailer表单,并且正在使用.ajax使用此SO答案jquery-ajax-post-example-with-php

它是成功发送还是不发送,所以我知道Mailer和验证码正在工作。现在,如果我能因成功和失败而采取不同的行为,那将是很好的,但我并没有以某种方式正确地做到这一点。

首选行为

成功->重新加载屏幕并显示带有成功消息的引导程序模式

失败->重新加载屏幕并显示带有失败消息的引导模式

我有很多代码,请尽可能多地考虑模式,而PHPMailer实际上也正在发送。我遇到的问题应该在下面的代码中,但是如果您还有其他问题,请询问。试图使问题尽可能整洁

  <script type="text/javascript">
$(document).ready(function() {
var request;

$("#contactForm").submit(function(event){
event.preventDefault();

// Abort any pending request
if (request) {
request.abort();
}

// setup some local variables
var $form = $(this);

// Let's select and cache all the fields
var $inputs = $form.find("input, select, button, textarea");

// Serialize the data in the form
var serializedData = $form.serialize();

// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
$inputs.prop("disabled", true);

request = $.ajax({
url: "processLogin.php",
type: "post",
data: serializedData
});

// Callback handler that will be called on success
request.done(function (response, textStatus, jqXHR){
if (response == true ) {
top.location.reload();
// top.location.href="/";
// $('#successEmail').modal('show');
} else {
// top.location.reload();
$('#failEmail').modal('show');
}
});

// Callback handler that will be called on failure
request.fail(function (jqXHR, textStatus, errorThrown){
// Log the error to the console
// console.error(
// "The following error occurred: "+
// textStatus, errorThrown
// );
// top.location.reload();
});

// Callback handler that will be called regardless
// if the request failed or succeeded
request.always(function () {
// Reenable the inputs
$inputs.prop("disabled", false);
});

});
});
</script>


PHPMailer表格

<?php
session_start();
?>
<?php
/**
* This example shows how to handle a simple contact form.
*/
$msg = '';


use PHPMailer\PHPMailer\PHPMailer;

require './mail/PHPMailer.php';
require './mail/Exception.php';
require './mail/SMTP.php';
require './mail/PHPMailerAutoload.php';

include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';

$securimage = new Securimage();

//Don't run this unless we're handling a form submission
if (array_key_exists('email', $_POST)) {
date_default_timezone_set('Etc/UTC');

//Create a new PHPMailer instance
$mail = new PHPMailer;

$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = 'smtp.live.com';
$mail->SMTPAuth = true;
$mail->Username = 'email@outlook.com';
$mail->Password = 'password';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;

$mail->setFrom('email@outlook.com', 'Mailer');
$mail->addAddress('email@outlook.com', 'First Last');


$email = isset($_POST['email']) ? $_POST['email'] : null;
$name = isset($_POST['name']) ? $_POST['name'] : null;
$phone = isset($_POST['phone']) ? $_POST['phone'] : null;
$message = isset($_POST['message']) ? $_POST['message'] : null;


if ($mail->addReplyTo($_POST['email'], $_POST['name'])) {
$mail->Subject = 'Contact request';
$mail->isHTML(true);
$mail->Body = <<<EOT
<div style="width:100%">
<div><label style="color: #044F69; font-weight:bold">Email:</label> <span>{$_POST['email']}</span></div>
<div><label style="color: #044F69; font-weight:bold">Name:</label> <span>{$_POST['name']}</span></div>
<div><label style="color: #044F69; font-weight:bold">Phone:</label> <span>{$_POST['phone']}</span></div>
<div><label style="color: #044F69; font-weight:bold">Message:</label> <span>{$_POST['message']}</span></div>
</div>
EOT;

if ($securimage->check($_POST['captcha_code']) == false) {
// echo "<meta http-equiv='refresh' content='0'>";
exit;
}

//Send the message, check for errors
if (!$mail->send()) {
$msg = 'Sorry, something went wrong. Please try again later.';
} else {
header("Location: /");
exit;
}
} else {
$msg = 'Invalid email address, message ignored.';
}
}
?>


附言我所拥有的代码(请参见上文)显示了失败模式,无论通过还是失败,都不会重新加载。

提前致谢!

最佳答案

您选择了一个相对困难的示例进行学习。成功/失败后重新加载意味着您​​需要引入会话或cookie或URL参数以跟踪请求之间的状态。您需要正确处理几个运动部件。您必须有这样做的理由,但是如果您无需重新加载就可以脱身,这将简化事情,并且可能会带来更好的用户体验。我在以下两个选项中都包含了信息。

首先,PHP。您有几种可能的退出状态,具体取决于电子邮件是否已成功发送等,但它们的处理方式不一致。在一种情况下,它会进行重定向,在某些情况下,它会以静默方式退出。所有情况应保持一致;无论发生什么情况,对该PHP页面的请求均应生成一个响应,并且最好将该响应传递回调用Java脚本,以便它可以对发生的任何事情进行处理。

似乎您开始进行设置,但未完成设置-您准备了一个$msg包含发生了什么的信息,但从未显示过,并且$msg在一些退出案例中完全丢失了(特别是成功情况以及验证码失败的情况)。

除了您的$msg外,我还将添加一个status标志,以便JS可以轻松判断请求是否成功;由于您正在用JS阅读此响应,因此我将其设为JSON。

请注意,由于您想在成功/失败两种情况下都重新加载页面,严格来说,JSON响应并不是真正必要的,但我认为这是一个好习惯,并且将有助于开发过程中的调试。

为了确保每个退出条件都能生成标准响应,我不得不将实际的邮件发送代码嵌套在CAPTCHA测试中。该IMO有点混乱,我个人将进行重组,以returning early简化各种条件的测试,因此您最终不会进行3-4个嵌套测试。例如,不要将所有内容嵌套在array_key_exists('email', $_POST)测试中,而是测试相反的内容(如果没有电子邮件值),并在失败时立即退出。

// Don't run this unless we're handling a form submission
if (!array_key_exists('email', $_POST)) {
// Generate response and bail out!
echo $some_response_or_whatever;
die();
}


我还建议您重新考虑流程,例如,如果CAPTCHA失败,您是否真的要重新加载只是为了显示该错误?您正在破坏使用AJAX的好处之一-无需重新加载即可获取响应。也许如果失败,您可以在用户单击“提交”的表单上显示错误消息。如果成功,则打开模态,并在必要时重新加载。

我在下面所做的更改的摘要:


$mail->send()嵌套在CAPTCHA条件内;
创建一个 $response,其中包含用于验证码失败的相应消息;
创建成功案例的 $response
在所有响应中添加 status标志;
$response添加到会话中,以便在页面重新加载后可用;
最后,将响应作为JSON回显,以便调用AJAX可以告诉发生了什么。


这是更新的缩写代码(我删除了大块未更改的代码)代码:

<?php
session_start();

// ... your code

//Don't run this unless we're handling a form submission
if (array_key_exists('email', $_POST)) {

// ... your code

if ($mail->addReplyTo($_POST['email'], $_POST['name'])) {

// ... your code

if ($securimage->check($_POST['captcha_code']) == false) {
// Generate a response in this failure case, including a message and a status flag
$response = [
'status'=> 1,
'msg' => 'CAPTCHA test failed!'
];

} else {
//Send the message, check for errors
if (!$mail->send()) {
// Generate a response in this failure case, including a message and a status flag
$response = [
'status'=> 1,
'msg' => 'Sorry, something went wrong. Please try again later.'
];
} else {
// Generate a response in the success case, including a message and a status flag
$response = [
'status'=> 0,
'msg' => 'Success!'
];
}
}
} else {
// Generate a response in this failure case, including a message and a status flag
$response = [
'status'=> 1,
'msg' => 'Invalid email address, message ignored.'
];
}
}

// Add the response to the session, so that it will be available after reload
$_SESSION['response'] = $response;

// Finally display the response as JSON so calling JS can see what happened
header('Content-Type: application/json');
echo json_encode($response);
?>


接下来,您的Javascript。由于您希望页面在成功和失败情况下都重新加载,因此您实际上不需要测试响应。

request.done(function (response, textStatus, jqXHR){
// You could test the response here, but since both success and failure
// should reload, there is no point.
window.location.reload();

// If you did want to test response and act on it, here's how to do that:
/*
if (response.status == 0) {
// Success! Do something successful, like show success modal
$('#successEmail').modal('show');
} else {
// Oh no, failure - notify the user
$('.message').html(response.msg);
}
*/
});


您没有在描述中提及 fail情况下会发生什么。请注意,当请求失败(例如404或超时等)时,将触发 fail回调,而不是在触发失败情况之一(如无效电子邮件)时触发。在这种情况下,我只会在前端生成一个味精,而无需重新加载:

request.fail(function (jqXHR, textStatus, errorThrown){
// Say you have a <div class="message"></div> somewhere, maybe under your form
$('.message').html('Error: ' + textStatus + ', ' + errorThrown)
});


因此,现在您的PHP已启动,设置了会话变量并返回了,并且您的JS重新加载了页面。您需要测试会话变量的内容,并相应地触发一些JS。在前端页面上,现有的 $(document).ready( ...内:

<script>
$(document).ready(function() {
var request;

// ... your code

<?php
// New PHP/JS to handle what happens when the page reloads
if (isset($_SESSION['response'])) {
if ($_SESSION['response']['status'] == 0) { ?>
// Success!
$('#successEmail').modal('show');
<?php } else { ?>
$('#failEmail').modal('show');
<?php }

// In both cases we need to clear the response so next reload does not
// fire a modal again
unset($_SESSION['response']);
} ?>
});
</script>


您可以使用 $_SESSION['response']['msg']在模态中访问成功/失败消息的内容。

另一个建议-如果您的成功和失败模式相似,则可以只使用其中一种,并使用Javascript更新其内容。

<script>
<?php if (isset($_SESSION['response'])) { ?>
// First add the message to the modal, assuming you have a
// <div class="message"></div> in your modal
$('#modal .message').html('<?php echo $_SESSION['response']['msg']; ?>');

// Now open the one modal to rule them all
$('#modal').modal('show');

<?php
unset($_SESSION['response']);
} ?>
</script>


旁注-我不确定您的 Abort any pending request是否确实在做您想要的事情。 request已在文档准备就绪时声明,因此它始终存在,AFAICT?

关于javascript - 在PHPMailer上成功/失败的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47718523/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com