使用Angular $ http服务获取PHP AJAX响应数据

时间:2017-01-03 07:57:23

标签: php angularjs json ajax angularjs-http

如果这是重复以前的问题,我很抱歉,但我找不到一个似乎与我的问题有关的解决方案&我是Angular的新手。

我有一个Angular表单,它与PHP通信数据以发送电子邮件,我的问题是处理来自PHP的JSON响应(因为PHP回传它是否在JSON本身内成功,以及消息) 。 我似乎无法根据JSON中包含的“成功”值来获取代码,也不会实际显示“消息。”

JSON响应数据看起来像这样(当它因电子邮件问题而失败时): enter image description here

所以我的角度代码需要根据“成功”是真还是假来响应,同时还要显示由AJAX在JSON中传递的“消息”。

My Angular Controller代码:

app.controller('ContactController', function ($scope, $http) {
    $scope.result = 'hidden'
    $scope.resultMessage;
    $scope.formData; //formData is an object holding the name, email, subject, and message
    $scope.submitButtonDisabled = false;
    $scope.submitted = false; 
    $scope.submit = function(contactform) {
        $scope.submitted = true;
        $scope.submitButtonDisabled = true;
        if (contactform.$valid) {
            var request = $http({
                method  : 'POST',
                url     : 'php/contact.php',
                data    : $.param($scope.formData),  //param method from jQuery
                headers : { 'Content-Type': 'application/x-www-form-urlencoded' } 
            });
            if (request.success) { 
                console.log(request);
                $scope.submitButtonDisabled = false;
                $scope.result='bg-success';
                $scope.resultMessage = request.message;
              } else {
                $scope.submitButtonDisabled = true;
                $scope.resultMessage = request.message;
                //$scope.resultMessage = "Opps!... something went wrong.  Please Contact OpenHouse directly to let them know of this error.";
                $scope.result='bg-danger';
            };
               //};
           } else {
            $scope.submitButtonDisabled = false;
            $scope.resultMessage = 'Failed <img src="http://www.chaosm.net/blog/wp-includes/images/smilies/icon_sad.gif" alt=":(" class="wp-smiley">  Please fill out all the fields.';
            $scope.result='bg-danger';
        }
    }
});

我的PHP代码:

<?php

  require_once ("class.phpmailer.php");   // Include phpmailer class
  ini_set('display_errors', 'On');
  error_reporting(E_ALL | E_STRICT);

  if (isset($_POST['inputFirstName']) && isset($_POST['inputLastName']) && isset($_POST['inputEmail']) && isset($_POST['inputPhone']) && isset($_POST['inputMessage'])) {

    //check if any of the inputs are empty
    if (empty($_POST['inputFirstName']) || empty($_POST['inputLastName']) || empty($_POST['inputEmail']) || empty($_POST['inputPhone']) || empty($_POST['inputMessage'])) {
        $data = array('success' => false, 'message' => 'Please fill out the form completely.');
        echo json_encode($data);
        exit;
    }

    $message=
    'First Name:    '.$_POST['inputFirstName'].'<br />
    Last Name:  '.$_POST['inputLastName'].'<br />
    Phone:  '.$_POST['inputPhone'].'<br />
    Email:  '.$_POST['inputEmail'].'<br />
    Comments:   '.$_POST['inputMessage'].'
    ';

    $mail = new PHPMailer();        // Instantiate the PHPMailer Class
    $mail->IsSMTP();                // enable SMTP
    $mail->SMTPDebug = 1;           // debugging: 1 = errors and messages, 2 = messages only
    $mail->SMTPAuth = true;         // SMTP authentication enabled
    $mail->SMTPSecure = 'ssl';      // secure transfer enabled + REQUIRED for Gmail (either SSL or TLS)
    $mail->Host = "smtp.gmail.com"; //Gmail SMTP Server to relay thru
    $mail->Port = 465; // Port 465 as we're using SSL... or use Port 587 for TLS
    $mail->IsHTML(true);                               // We're sending a HTML formatted message
    $mail->Username = "....@gmail.com"; // Gmail account for authentication
    $mail->Password = "*********";                     // Gmail password for authentication
    $mail->SetFrom("....@gmail.com");   // The email is being sent from this address
    $mail->Subject = "Website Contact Form Enquiry";   // The subject line of the email
    $mail->Body = ($message);                          // The actual email message to be sent
    $mail->AddAddress("....@gmail.com"); // The email is being sent to this address

   if(!$mail->send()) {
     echo json_encode(['success' => false, 'message' => 'Message could not be sent. Mailer Error: ' . $mail->ErrorInfo]);
     exit;
   }

   error_log("Data: ".$data['success']." Message: ".$data['message']);
   echo json_encode(['success' => true, 'message' => 'Thanks! We have received your message.']);

    } else {
      echo json_encode(['success' => false, 'message' => 'Please fill out the form completely.']);
    }
 ?>

2 个答案:

答案 0 :(得分:3)

首先,$ http不返回request对象,它返回一个用response对象解析的promise:

        //var request = $http({
        //It returns a promise
        var promise = $http({
            method  : 'POST',
            url     : 'php/contact.php',
            data    : $.param($scope.formData),  //param method from jQuery
            headers : { 'Content-Type': 'application/x-www-form-urlencoded' } 
        });
        //Use .then method to receive response
        promise.then(function (response) {
          var request = response.data; 
          if (request.success) {
            console.log(request);
            $scope.submitButtonDisabled = false;
            $scope.result='bg-success';
            $scope.resultMessage = request.message;
          }
        });

重要的是要意识到$ http服务会立即返回挂起承诺。当响应从服务器返回时,承诺稍后解决(要么已履行要么被拒绝)。

使用promise的.then方法提供成功和拒绝处理程序,以解决已完成或已拒绝的响应。

有关详细信息,请参阅:AngularJS $http Service API Reference - General Usage

<强>更新

默认情况下,AngularJS框架使用Content-Type: 'application/json'进行编码和发布。

要在PHP后端接收JSON数据,请执行以下操作:

$json = file_get_contents('php://input');
$obj = json_decode($json);

然后可以简化使用AngularJS的POST:

    var promise = $http({
        method  : 'POST',
        url     : 'php/contact.php',
        //data    : $.param($scope.formData),  //param method from jQuery
        data: $scope.data;
        //headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
        //Defaults to:
        //headers: {'Content-Type': 'application/json'} 
    });
    //Use .then method to receive response
    promise.then(function (response) {
      var request = response.data; 
      if (request.success) {
        console.log(request);
        $scope.submitButtonDisabled = false;
        $scope.result='bg-success';
        $scope.resultMessage = request.message;
      }
    });

答案 1 :(得分:0)

感谢大家的帮助; 我能够在asyn http call&amp;之后返回一个回复。在屏幕上显示... 但无论我尝试什么,它总是在数据响应中将HTTP标头与数据打包在一起。

如果PHP没有发送电子邮件(我删除了所有发送电子邮件的命令),那么数据响应就是数据。 如果PHP确实发送了一封电子邮件,那么响应将是数据响应中的HTTP标头+数据。

所以最后在Angular方面,我将数据响应转换为字符串,将该字符串拆分为{,这将为我提供一个只包含数据(并且没有标题)的新字符串,一些额外的\分隔字符串中的值,显然结束}

因此,通过字符串操作,我能够得到我想要的响应。

这是工作的角度控制器:

app.controller('ContactController', function ($scope, $http) {
    $scope.result = 'hidden'
    $scope.resultMessage;
    $scope.formData; //formData is an object holding the name, email, subject, and message
    $scope.submitButtonDisabled = false;
    $scope.submitted = false;
    $scope.submit = function(contactform) {
        $scope.submitted = true;
        $scope.submitButtonDisabled = true;
            var promise = $http({
                method  : 'POST',
                url     : 'php/contact.php',
                data    : {
                    firstname: $scope.formData.inputFirstName,
                    lastname: $scope.formData.inputLastName,
                    emailid: $scope.formData.inputEmail,
                    phoneno: $scope.formData.inputPhone,
                    message: $scope.formData.inputMessage
                },
                headers : {'Content-Type': 'application/json'}
            })
            promise.then(function (response) {
              var request = JSON.stringify(response.data);  //convert JSON data to string for manipulation
              var startpos = request.indexOf("{");          //locate '{' as its the start of the data we want
              var endpos = request.lastIndexOf("}");        //locate '}' as its the end of the data we want
              var res = request.slice(startpos, endpos);    //Extract the actual data now we know where it is.
              var newresponse = res.split("\\");            //Split the data into new array
              var answer = request.search("true");          //search the string to see if it contains the word "true" meaning an email was sent.

              if (answer >= 0) {
                $scope.submitButtonDisabled = false;
                $scope.result='bg-success';
                $scope.resultMessage = newresponse[5].replace('"', " ");
              } else {
                $scope.submitButtonDisabled = true;
                $scope.resultMessage = newresponse[5].replace('"', " ");
                $scope.result='bg-danger';
              }
          });
        }
    });