【问题标题】:Javascript fetch API and PHPMailer slow responseJavascript fetch API 和 PHPMailer 响应缓慢
【发布时间】:2020-08-10 14:43:34
【问题描述】:

当客户订购产品时,他们会将表单发送到服务器端。我在 php 中验证表单,如果没有错误,我会发送电子邮件给客户,然后给自己发一封电子邮件,其中包含从表单收到的产品信息。我使用 PHPMailer 发送电子邮件,但它相当慢,发送邮件并从服务器返回到 javascript 的响应需要 5 秒。当我取出发送电子邮件的代码时,响应立即到达。 PHPMailer 会减慢响应速度,但我不知道为什么。

Javascript:

 const form = document.querySelector("#form");
      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");
            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("Success!");
             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';

$errors = [];

if(isset($_POST["name"]) && isset($_POST["address"]) && isset($_POST["email"]))  {
    $name = $_POST["name"];
    $address = $_POST["address"];
    $email = $_POST["email"];

    //I skipped the validation for shorter code
    if(empty($name)) {
        $errors[] = "Name cannot be empty!";
    }

    if(empty($address)) {
        $errors[] = "Address cannot be empty!";
    }


    if (!empty($errors)) {
        echo json_encode($errors); //Sending back the array of string errors
    } else {
        $mail = new PHPMailer();
        $mail->CharSet = "UTF-8";
        $contentBody = '<html><body><div  style="text-align:center; width: 500px; display:block; margin-left: auto; 
        margin-right: auto;"><p style="text-align:center;"><h2>' . $name . ' ' . $address . '</div></body></html>';

        //Sending to client
        $mail->setFrom("mymail@gmail.com", "MyName"); //Who is sending the message
        $mail->addAddress($email); //Set who the message is to be sent to
        $mail->AddReplyTo("mymail@gmail.com", "MyName");
        $mail->Subject = 'Order';
        $mail->isHTML(TRUE);
        $mail->Body = $contentBody;
        $mail->isSMTP();
        $mail->Host = 'smtp.gmail.com';
        $mail->SMTPAuth = TRUE;
        $mail->SMTPSecure = 'tls';
        $mail->Username = "mymail@gmail.com";
        $mail->Password = 'mypassword';
        $mail->Port = 587;
        if(!$mail->Send())
        {
            echo "Something went wrong!";
        }
        $mail2 = new PHPMailer();
        $mail2->CharSet = "UTF-8";
        //Sending to myself
        $contentBodyForFirm = '<html><body><div  style="text-align:center; width: 500px; display:block; margin-left: auto; 
        margin-right: auto;"><p style="text-align:center;"><h2>' . $name . ' ' . $address . '</div></body></html>';

        $mail2->setFrom($email, $name); //Who is sending the message
        $mail2->addAddress("mymail@gmail.com"); //Set who the message is to be sent to
        $mail2->Subject = 'Order';
        $mail2->isHTML(TRUE);
        $mail2->Body = $contentBodyForFirm;
        $mail2->isSMTP();
        $mail2->charSet = "UTF-8";
        $mail2->Host = 'smtp.gmail.com';
        $mail2->SMTPAuth = TRUE;
        $mail2->SMTPSecure = 'tls';
        $mail2->Username = "mymail@gmail.com";
        $mail2->Password = 'mypassword';
        $mail2->Port = 587;
        if(!$mail2->Send())
        {
            echo "Something went wrong!";
        }
        echo json_encode([]); //Sendning back an empty array

    }
}

?>

如果验证中出现错误,我会使用echo json_encode($errors); 发回错误并在客户端显示它们。如果没有错误,我使用echo json_encode([]);。在 javascript 中,我检查 fetch 响应。如果它是一个空数组,则没有错误,我可以重定向到 index.html。

【问题讨论】:

  • 你知道它是不是因为你的代码或者其他原因而变慢?我会先仔细查看浏览器中的网络选项卡,看看它是否不是别的东西。在网络选项卡中,单击请求,然后单击“时间”子选项卡(至少在 Chrome 中)
  • @paddotk 我检查了,这里是详细信息: 资源调度:排队 2.51ms 连接开始:停滞 1.07ms 请求/响应:请求发送 0.18ms 等待(TTFB)3.95s 内容下载:1.10ms解释:3.95s
  • 我不确定这一点,但对我来说,“等待”似乎是在发送请求后发生的;即等待服务器响应。在这种情况下,它与您的代码无关。
  • @paddotk 最近的服务器更改可能有问题。还是谢谢你。

标签: javascript php fetch phpmailer


【解决方案1】:

这很可能是因为 SMTP 通常很慢(有时是故意的),尤其是在与远程服务器通信时。在页面/请求处理期间发送根本不适合 SMTP,尽管这并不能阻止很多人这样做。

使其更快更快的最佳方法是通过本地邮件服务器进行中继。这样就没有网络开销并且响应时间会非常快——您应该可以每秒发送数百条消息。它还将为您处理排队、限制、重试等。

PHPMailer wiki 有 notes on how to send to lists efficiently,它也主要适用于您发送 > 1 条消息时。看看list sending example,它体现了这个建议。在您的情况下,您正在创建 PHPMailer 的第二个实例以发送第二条消息。您最好对第二条消息重复使用同一个实例并使用 keepalive,这会大大减少连接开销。

【讨论】:

  • 如果我使用本地邮件服务器,是否需要运行我的计算机 0/24?
  • 不,就在你发送的时候和之后的一段时间。
  • 但是问题是我不知道客户什么时候下单。。邮件发送应该是自动的。
  • 那么找个服务器?这就是他们的目的!如果您有网络服务器,它也可以用作邮件服务器。
  • 我认为你将不得不忍受它。 jQuery 和 fetch 之间不会有明显的区别。或者,从 scaleway 之类的地方获取合适的服务器;每月只需​​大约 3 美元。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
相关资源
最近更新 更多