循环调用jQuery Ajax会给我503错误

时间:2018-09-28 19:54:22

标签: php jquery ajax

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

  • PHP 5.6.31
  • MySQL 5.5.45
  • Windows Server 2016
  • jQuery 1.11.1

如果我有少量的客户(例如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是否会受到服务器设置的影响,因此我一直在暗中刺伤。为了解决此问题,我做了以下事情:

  • 我将memory_limit从128MB增加到512MB
  • 我将max_input_time从20增加到60
  • 我将post_max_size从20M增加到了60M
  • 我将upload_max_filesize从10M增加到了30M
  • 我将max_file_uploads从20增加到60

全部无济于事。

这是我的chrome开发人员工具的屏幕截图,因此您可以确切地了解我的意思。不用担心关于失败电子邮件的红色警告-那些只是没有电子邮件地址的电子邮件。真正的问题是对send-invoice.php的调用出现503错误。有趣的是,这些错误甚至在文件被处理之前就已显示出来。它们几乎都在同一时间从待处理变为错误,就像服务器在某个时刻只是说“我完成了-再也没有”一样。

enter image description here

不确定send-invoice.php的内容是否相关,但无论如何都可以:

<?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 个答案:

答案 0 :(得分:1)

我最终要做的是摆脱循环,只在上一封完成后才发送下一封电子邮件。基本上,这是成功的回调。因此,这种方式我不会同时执行一堆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);
          }
        }
   });
}

这项工作的关键是在每次调用函数时增加传递的索引。

答案 1 :(得分:-1)

听起来像脚本达到了最大执行时间。检查此答案,看看是否有帮助https://stackoverflow.com/a/5140299/6312181