【问题标题】:Getting PHP AJAX response data with Angular $http Service使用 Angular $http 服务获取 PHP AJAX 响应数据
【发布时间】:2017-05-17 06:27:21
【问题描述】:

很抱歉,如果这是重复之前的问题,但我无法找到似乎可以解决我的问题并且我是 Angular 新手的解决方案。

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

JSON 响应数据如下所示(由于电子邮件问题而失败时):

所以我的 Angular 代码需要根据“成功”是真还是假来做出响应,同时还要显示由 AJAX 以 JSON 格式传递的“消息”。

我的 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;
        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.']);
    }
 ?>

【问题讨论】:

  • 了解$http 服务。 $http 不返回响应正文,它返回一个带有响应对象的承诺,其中包含响应正文以及其他内容,例如标头、状态等。
  • 另外,为了让 Angular 自动解析您从 PHP 到对象而不是 JSON 字符串的响应,您应该在响应中返回 content-type: application/json 标头,
  • @BlissSol 扩展了 Ron Dadon 的答案,因为 $http 是异步的,并且 request 变量返回一个承诺,而不是 if (request.success) 你会想要 request.then( function(response) { if (response.data.success) { ... } } )

标签: php angularjs json ajax angularjs-http


【解决方案1】:

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

        //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 服务会立即返回一个 pending 承诺。当响应从服务器返回时,承诺会在稍后解决(履行或拒绝)。

使用 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;
      }
    });

【讨论】:

  • 我已经完成了所有人推荐的所有更改,但我仍然为变量“request.message”得到“未定义”?此外,通过您建议@georgawg 的更改,“请求”仍然返回与我最初发布的完全相同的 JSON 数据(因此,我无法访问 JSON 中包含的“成功”或“消息”的值。
  • 我的问题会不会是因为“成功”和“消息”的值在打包为 JSON 并返回之前被打包在一个数组中(在 PHP 端)?
【解决方案2】:

感谢大家的帮助; 我能够在异步 http 调用后返回响应并将其显示在屏幕上... 但无论我尝试什么,它总是在数据响应中将 HTTP 标头与数据打包在一起。

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

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

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

这是工作的 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';
              }
          });
        }
    });

【讨论】:

    猜你喜欢
    • 2018-09-14
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 2019-10-07
    • 1970-01-01
    相关资源
    最近更新 更多