【问题标题】:Submit form on button click with FETCH and send an email with PHPMailer使用 FETCH 单击按钮提交表单并使用 PHPMailer 发送电子邮件
【发布时间】:2020-08-04 21:18:02
【问题描述】:

我想通过 fetch API 向 index.php 发送一个按钮点击表单,并在其中验证表单。如果表单中没有错误,我想用 PHPMailer 向客户端发送一封电子邮件。由于某种原因,客户端没有收到电子邮件。 我已经搜索了几个小时的答案,但我无法解决问题。

这里是javascript代码:

 const form = document.querySelector("#myForm");
      form.addEventListener("submit", (e) => {
        e.preventDefault();
        const formData = new FormData(form);
        fetch("index.php", {
          method: 'post',
          body: formData
        }).then((resp) => resp.json())
        .then(function (text) {
          console.log(text); //Do something with the response, which is an array
          if(text !== undefined && text.length > 0) { //The array isn't empty
            //Show errors
            const formdiverror = document.querySelector(".col-100-form-error");
            const colform = document.querySelector(".col-100-form"); //showing error
            colform.style.display = "block";
            formdiverror.innerHTML = "";
            text.forEach(t => formdiverror.innerHTML += t + "</br>");
          } else {
            //array is empty, no errors
             const colform = document.querySelector(".col-100-form");
             if(colform !== null || colform !== undefined) colform.style.display = "none";
             alert("You succesfully bought the product!");
            //window.location.replace("index.html"); //if there was no error redirect to index.html
          }
        });
      })

php:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
require 'Exception.php';
require 'PHPMailer.php';
require 'SMTP.php';
require 'PHPMailerAutoload.php';
require "class.phpmailer.php";
require "class.smtp.php";


$errors = [];

if(isset($_POST["name"])) {
   
     /*I took out the validation to simplify the code*/
    if (!empty($errors)) {
        echo json_encode($errors);
    } else {
        echo json_encode([]);
        $mail = new PHPMailer();
        $mail->isSMTP();
        $mail->Host = 'smtp.gmail.com';
        $mail->SMTPAuth = true;
        $mail->Username = "mymail@gmail.com"; //paste one generated by Mailtrap
        $mail->Password = 'mypasswd'; 
        $mail->SMTPSecure = 'tls'; // secure transfer enabled REQUIRED for GMail
        $mail->Port = 587;
        $mail->addAddress("customer@gmail.com", 'First Last');
        $mail->addReplyTo('mymail@gmail.com', 'First Last');
        $mail->setFrom('mymail@gmail.com', 'John Doe');
        $mail->Subject = 'PHPMailer GMail SMTP test';
        $mail->isHTML(true);
        $mailContent = "<h1>Send HTML Email using SMTP in PHP</h1>
        <p>This is a test email I’m sending using SMTP mail server with PHPMailer.</p>";
         $mail->Body = $mailContent;
         $mail->send();
        //If I try this way it gives an errror: Unexpected token in JSON at position 
        /* if($mail->send()){
            echo ('Message has been sent');
        }else{
            echo ('Message could not be sent.');
            echo ('Mailer Error: ' . $mail->ErrorInfo);
        }*/
    }
} 
?>

我没有收到任何错误,所以我不知道问题出在哪里。 我已禁用双向验证,并允许访问不太安全的应用程序。

【问题讨论】:

  • 尝试添加 $mail->SMTPDebug = 2;在您的 PHP 文件中并检查日志。它将对这个问题给出一个公平的想法。
  • 为什么是这条线? echo json_encode([]); ?这肯定会解释错误If I try this way it gives an errror: Unexpected token in JSON at position...
  • @ProfessorAbronsius 我使用 echo json_encode([]);这样我就知道在客户端我在表单验证中没有任何错误。
  • 如果您在发送标头之前输出内容,您通常会遇到错误,并且由于 Fetch 函数需要 json,因此来自 PHP 的响应应该是 json 而不是像上面那样的纯文本.. 否则更改 (resp) =&gt; resp.json()对于(resp) =&gt; resp.text()
  • @ProfessorAbronsius 如果我使用 resp.json(),那么每次在 php 中都需要使用 echo json_encode() 吗?我将数组发送到客户端,其中包含验证的错误(字符串)。如果我使用 resp.text() 和 console.log()-it,它只会打印“array”。

标签: javascript php fetch phpmailer


【解决方案1】:

首先,您要导入 PHPMailer 的 both 版本 5 和 6!那不会很顺利; 6. 删除这些行和它们指向的文件;你不需要它们:

require 'PHPMailerAutoload.php';
require "class.phpmailer.php";
require "class.smtp.php";

如果您对如何导入库感到困惑,那么现在是了解composer 的好时机。

奇怪的是,当您注释掉显示错误所在的代码时,当出现错误时它不再显示...console.log(text); 行也应该显示您的浏览器看到的内容。

解决此问题的最佳方法是一次调试一件事。

首先确保您的表单实际上以应有的格式将数据传递给您的脚本——考虑到 JSON 错误(不是来自 PHPMailer),这似乎很可能是 不是 em> 的情况,这可能是你所有问题的根源。所以在你的脚本顶部附近添加这个:

var_dump($_REQUEST);

这会破坏您的 ajax 请求(因为输出不是 JSON),但您将能够在浏览器的 Web 检查器中看到原始响应。

确认格式正确并包含所有预期的表单数据后,删除var_dump 行并继续检查您是否正确访问了 JSON 中的属性。同样,您可能会发现最好在浏览器的检查器中显示此内容。一旦确定以正确的方式提取所需的所有数据位,就可以继续发送电子邮件了。

鉴于通过 SMTP 使用 gmail 的非常常见问题,最好使用固定值测试您的电子邮件代码,与您的 ajax 东西分开 - 没有其他东西就很难自行调试碍事。

现在您已经到了所有单独部分都可以工作的地步,将它们重新组合在一起并检查每个步骤。

【讨论】:

  • 感谢您的建议。我试图只执行没有任何 ajax 的邮件功能,结果发现我对 gmail 有一些问题。我不得不重新登录该帐户,它以某种方式解决了问题。
  • 是的,gmail 就是这样做的。 PHPMailer 故障排除指南中对此进行了介绍,但是您需要能够看到它发生才知道要查找它,并且使用 Ajax 比传统的页面加载更难做到这一点。很高兴你解决了。
  • 我还有一个问题。邮件有效,但获取响应需要很长时间才能到达。有时它会等待 1-2 秒,但有时甚至会等待 7-8 秒。您知道导致问题的原因吗?
  • 是的,电子邮件,尤其是到远程服务器的 SMTP 可能非常慢,通常是故意的。它确实不适合在页面/请求处理期间同步发送,尽管这并不能阻止很多人尝试这样做。加快此速度的最佳方法是将您的发送请求与 SMTP 进程分离,而最简单的方法是通过本地邮件服务器中继您的消息。这会将您的发送时间(从您的脚本中可以看出)减少到几分之一秒。
  • 我明白了。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
  • 2017-08-07
  • 1970-01-01
  • 2011-08-04
相关资源
最近更新 更多