代码之家  ›  专栏  ›  技术社区  ›  Vincent

在循环中调用jqueryajax会导致503个错误

  •  -1
  • Vincent  · 技术社区  · 6 年前

    我使用jqueryajax生成报告并通过电子邮件将这些报告发送给客户。

    • MySQL 5.5.45版本
    • Windows服务器2016

    如果我有少量的客户(比如50个),这没问题,但是如果我有100个或更多的客户,那么我就会得到503个错误。第一批邮件不会有问题,但在某个时刻,所有“挂起”的电子邮件脚本调用都会报告503个错误。通常在45秒左右。

    这是我的javascript

    function emailInvoices(){
    
      $('#emailreportbutton').button("option","disabled", true);
      $('#email-progresslabel').text( "Starting..." );
    
      var recipientarray = $('#recipientarray').val();
      var recipients = JSON.parse(recipientarray);
      var recipientcount = recipients.length;
    
      var totaldueoption = $('#totaldueoption').val();
      var showaccountnumber = $('#showaccountnumber').val();
      var showmessage = $('#showmessage').val();
      var message = $('#message').val();
      var currentcount = 1;
      var successcounter = 0;
      var failcounter = 0;
    
      //<!--*** For each invoice returned... ***-->
    
      for (var i=0; i<recipientcount; i++){
        var obj = recipients[i];
    
        //<!--*** Generate and email the pdf ***-->
    
        $.ajax({
              type: 'POST',
              url: 'send-invoice.php',
              data: {
              familyid:recipients[i].familyid,
              invoicenumber:recipients[i].invoicenumber,
              motheremail:recipients[i].motheremail,
              fatheremail:recipients[i].fatheremail,
              primarypayer:recipients[i].primarypayer,
              primarypayeremail:recipients[i].primarypayeremail,
              invoicedate:recipients[i].invoicedate,
              totaldueoption:totaldueoption,
              showaccountnumber:showaccountnumber,
              showmessage:showmessage,
              message:message
              },
              success: function(data) {
                if(data == "success"){
                  successcounter ++;
                  $('#successcount').html(successcounter + " Sent");
                  if(failcounter == 0) $('#successcount').addClass('emailsuccess');
                }
                if(data == "fail"){
                  failcounter ++
                  $('#failcount').html(failcounter + " Failed");
                  $('#failcount').addClass('emailfail');
                  $('successcount').removeClass('emailsuccess');
                }
    
                //<!--*** Update progress bar ***-->
    
                var percentComplete = Math.round(currentcount * 100 / recipientcount);
                $('#progressbar').progressbar("value", percentComplete);
    
                currentcount ++;
    
              },
              error: function() {
              // Failed to call send-invoice.php
              }
        });
    
      }
    
      $('#reportlink').html("<a href=# onclick=runReport('emailhistory')>Click here to view your email history report</a>");
    }
    

    它以前一直有效,但在过去几个月里我一直在更改一些服务器设置,试图解决一个不相关的问题,所以我想知道我是否更改了任何PHP设置来引入这个问题。

    我不确定在这样的循环中调用ajax是如何受到服务器设置的影响的,所以我一直在暗中摸索。为了解决这个问题,我做了以下工作:

    • 我将内存限制从128MB增加到512MB
    • 我把最大尺寸从20米增加到60米
    • 我把上传文件的最大大小从10米增加到30米

    一切都无济于事。

    这是我的chrome开发者工具的截图,你可以完全理解我的意思。不要担心失败邮件的红色警告-那些只是没有电子邮件地址的邮件。真正的问题是调用send-invoice.php时出现503错误。有趣的是,这些文件在处理之前就出现了这个错误。它们几乎在同一时间从挂起变为错误,就好像在某个时刻服务器只是说“我完成了-再也没有了”。

    enter image description here

    <?php
    
    include("common/common.php");
    
    $familyid = $_POST["familyid"];
    $invoicenumber = $_POST["invoicenumber"];
    $motheremail = trim($_POST["motheremail"]);
    $fatheremail = trim($_POST["fatheremail"]);
    $primarypayer = trim($_POST["primarypayer"]);
    $primarypayeremail = trim($_POST["primarypayeremail"]);
    $attachmentdate = $_POST["invoicedate"];
    
    $totaldueoption = $_POST["totaldueoption"];
    $showaccountnumber = $_POST["showaccountnumber"];
    $showmessage = $_POST["showmessage"];
    $message = $_POST["message"];
    $dosend = false;
    
    //<!--********************************************************************************************************-->
    //<!-- Get family name -->
    //<!--********************************************************************************************************-->
    
    $sql = "select name from families where id = ".$familyid;
    $result = mysql_query($sql);
    
    if ($row = mysql_fetch_array($result)){
      $familyname = $row["name"];
    }
    
    //<!--********************************************************************************************************-->
    //<!-- Get email body -->
    //<!--********************************************************************************************************-->
    
    $sql = "select emailbodyinvoice from preferences where companyid = ".$companyid;
    $result = mysql_query($sql);
    
    if ($row = mysql_fetch_array($result)){
      $emailbody = $row["emailbodyinvoice"];
    }
    
    //<!--********************************************************************************************************-->
    //<!-- Generate pdf -->
    //<!--********************************************************************************************************-->
    
    include("common/pdf/mpdf/mpdf.php");
    ob_start();
    $report = "invoice";
    $selectedinvoice = $invoicenumber;
    include("report.php");
    $reporthtml = ob_get_clean();
    
    $style = "
    <style>
    @page {
      margin: 0px;
    }
    </style>";
    
    $html = $style.$reporthtml;
    
    $mpdf=new mPDF('c');
    
    $mpdf->mirrorMargins = true;
    $mpdf->SetDisplayMode('fullpage','two');
    $mpdf->WriteHTML($html);
    
    $invoice = $mpdf->Output('Invoice '.$attachmentdate,'S');
    
    //<!--********************************************************************************************************-->
    //<!-- Send invoice email -->
    //<!--********************************************************************************************************-->
    
    require('common/html2text.php');
    
    $emailbody = rawurldecode(html_entity_decode("<html><body>".$emailbody."<br><br><div style='color:#929292'>This email was sent on behalf of ".$companyname.".  You may reply to this message to contact ".$companyname." but do not use the sender address (no-monitor@timesavr.net) as that mailbox is not monitored and ".$companyname." will not receive your message.</div></body></html>"));
    
    $emailtextbody = html2text(html_entity_decode($emailbody));
    $emailsubject = "Invoice from ".$companyname;
    
    //<!--********************************************************************************************************-->
    //<!-- Include dependencies
    //<!--********************************************************************************************************-->
    
    require("common/smtpemail.php");
    
    //<!--********************************************************************************************************-->
    //<!-- Email sender details
    //<!--********************************************************************************************************-->
    
    $mail->From     = "no-monitor@timesavr.net";  // Approved sending domain for SendGrid so the emails don't get flagged as spam
    $mail->FromName = $companyname;
    $mail->AddReplyTo($companyemail,$companyname);
    $mail->AddStringAttachment($invoice,'Invoice '.$attachmentdate.'.pdf');
    
    //<!--********************************************************************************************************-->
    //<!-- Add recipients
    //<!--********************************************************************************************************-->
    
    $mothervalid = validateEmail($motheremail);
    $fathervalid = validateEmail($fatheremail);
    $primarypayervalid = validateEmail($primarypayeremail);
    
    if($emailinvoicesto == "P"){
      if($primarypayervalid){
        $mail->AddAddress($primarypayeremail,$primarypayeremail);
        $recipient = $primarypayeremail;
        $dosend = true;
      }
    }
    
    if($emailinvoicesto == "M" or $emailinvoicesto == "B"){
      if($mothervalid){
        $mail->AddAddress($motheremail,$motheremail);
        $recipient = $motheremail;
        $dosend = true;
      }
    }
    
    if($emailinvoicesto == "F" or $emailinvoicesto == "B"){
      if($fathervalid){
        $mail->AddAddress($fatheremail,$fatheremail);
        if($recipient <> ""){
          $recipient .= ";".$fatheremail;
        }else{
          $recipient .= $fatheremail;
        }
        $dosend = true;
      }
    }
    
    //<!--********************************************************************************************************-->
    //<!-- Send email
    //<!--********************************************************************************************************-->
    
    $emailsubject = htmlentities($emailsubject,ENT_QUOTES);
    $familyname = htmlentities($familyname,ENT_QUOTES);
    
    if($dosend){
      if($mail->Send()){
        recordEmail("I",$emailsubject,$familyname,$recipient,"S");
        $result = "success";
    
      }else{
        recordEmail("I",$emailsubject,$familyname,$recipient,"F");
        $result = "fail";
    
      }
    }else{
      recordEmail("I",$emailsubject,$familyname,$recipient,"F","No email address found");
      $result = "fail";
    }
    
    echo $result;
    
    mysql_close();
    ?>
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Vincent    6 年前

    最后我做的是摆脱循环,只在上一封邮件发送完毕后再发送下一封邮件。基本上是对成功的回馈。这样我就不需要同时执行一堆ajax调用,而是一次执行一个。

    它实现了与同步执行(async=false)相同的功能,但是这样就不会锁定UI,我仍然可以增加进度条。

    //<!--********************************************************************************************************-->
    //<!-- emailInvoices()
    //<!--********************************************************************************************************-->
    
    function emailInvoices(){
    
      var recipientarray = $('#recipientarray').val();
      var recipients = JSON.parse(recipientarray);
      var recipientcount = recipients.length;
    
      //<!--*** Pass in recipient array, first index and total recipient count... ***-->
      emailInvoice(recipients,0,recipientcount);
    }
    
    //<!--********************************************************************************************************-->
    //<!-- emailInvoice(recipient,i,recipientcount)
    //<!--********************************************************************************************************-->
    
    
    function emailInvoice(recipients,i,recipientcount){
    
      $.ajax({
            type: 'POST',
            url: 'send-invoice.php',
            data: {
              familyid:recipients[i].familyid,
              invoicenumber:recipients[i].invoicenumber,
              motheremail:recipients[i].motheremail,
              fatheremail:recipients[i].fatheremail,
              primarypayer:recipients[i].primarypayer,
              primarypayeremail:recipients[i].primarypayeremail,
              invoicedate:recipients[i].invoicedate,
              totaldueoption:totaldueoption,
              showaccountnumber:showaccountnumber,
              showmessage:showmessage,
              message:message
            },
            success: function(data) {
    
              //<!--*** Update progress bar ***-->
              var percentComplete = Math.round((i+1) * 100 / recipientcount);
              $('#progressbar').progressbar("value", percentComplete);
    
              //<!--*** Increment index and call this function again -->
              i++;
              if(i < recipientcount){
                emailInvoice(recipients,i,recipientcount);
              }
            }
       });
    }
    

    实现这一点的关键是在每次调用函数时增加传递的索引。