Mailchimp API 调用使用 AJAX

Posted

技术标签:

【中文标题】Mailchimp API 调用使用 AJAX【英文标题】:Mailchimp API call using AJAX 【发布时间】:2017-09-04 20:10:37 【问题描述】:

我正在使用

error:function(exception)alert('Exception:'+ JSON.stringify(exception));

如果出现 AJAX 错误,则显示异常,这是我得到的响应:

Exception:"readyState":4,"responseText":"","status":200,"statusText":"OK"

这对我来说似乎是一个成功的响应,但它是在 error 上调用的函数,这意味着出了点问题。

这里是页面:http://cuttingedgeconversions.com/free-month.html

我有一个成功的 API 调用来使用表单操作订阅一个新的电子邮件地址给邮件黑猩猩。但我不想在提交表单后重定向到另一个页面,所以我取出了“表单操作”属性,并尝试将此 API 调用添加到使用 ajax 的 script.js。

这里是 HTML:

<form class="email_form_freemonth" method="post">
<h3>Get your first month free</h3>
<div class="form-group customised-formgroup"> <span class="icon-user"></span>
<input type="text" name="full_name" class="form-control" placeholder="Name">
</div>
<div class="form-group customised-formgroup"> <span class="icon-envelope"></span>
<input type="email" name="email" class="form-control" placeholder="Email">
</div>
<!--<div class="form-group customised-formgroup"> <span class="icon-telephone"></span>
<input type="text" name="phone" class="form-control" placeholder="Phone (optional)">
</div>-->
<div class="form-group customised-formgroup"> <span class="icon-laptop"></span>
<input type="text" name="website" class="form-control" placeholder="Website (optional)">
</div>
<!--<div class="form-group customised-formgroup"> <span class="icon-bubble"></span>
<textarea name="message" class="form-control" placeholder="Message"></textarea>
</div>-->
<div>
<br>
<button style="margin: 0 auto" name="submit" type="submit" class="btn btn-fill full-width">GET FREE MONTH<span class="icon-chevron-right"></span></button>
</div>
</form>

这里是 freemonth_action.php(在 script.js 中调用,见下文):

<?php

session_start();
if($_SERVER['REQUEST_METHOD'] == "POST")
    $name = trim($_POST['full_name']);
    $email = trim($_POST['email']);
    if(!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL) === false)
        // MailChimp API credentials
        $apiKey = '*****';
        $listID = '0cf013d1d9';

        // MailChimp API URL
        $memberID = md5(strtolower($email));
        $dataCenter = substr($apiKey,strpos($apiKey,'-')+1);
        $url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $listID . '/members/' . $memberID;

        // member information
        $json = json_encode([
            'email_address' => $email,
            'status'        => 'subscribed',
            'merge_fields'  => [
                'NAME'     => $name,
            ]
        ]);

        // send a HTTP POST request with curl
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $apiKey);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        $result = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        //echo json_decode($result);

        // store the status message based on response code
        if ($httpCode == 200) 
            $_SESSION['msg'] = '<p style="color: #34A853">You have successfully subscribed to CodexWorld.</p>';
         else 
            switch ($httpCode) 
                case 214:
                    $msg = 'You are already subscribed.';
                    break;
                default:
                    $msg = 'Some problem occurred, please try again.';
                    break;
            
            $_SESSION['msg'] = '<p style="color: #EA4335">'.$msg.'</p>';
        
    else
        $_SESSION['msg'] = '<p style="color: #EA4335">Please enter valid email address.</p>';
    

我知道这些是正确的,因为当我使用 'form action = scripts/freemonth_action.php' 时它可以工作。但我不希望页面在提交时重定向,所以我在脚本中添加了一个由 script.js 触发的 ajax 调用。我现在在 script.js 中有 2 个 ajax 调用,第一个正在工作,但第二个没有。奇怪的是,BOTH RETURN STATUS CODE 200。

带有非嵌套 Ajax 调用的 script.js - 现在可以正常工作:

$('.email_form_freemonth').on('submit', function (e) 
        e.preventDefault();
        var _self = $(this);
        var __selector = _self.closest('input,textarea');
        _self.closest('div').find('input,textarea').removeAttr('style');
        _self.find('.msg').remove();
        _self.closest('div').find('button[type="submit"]').attr('disabled', 'disabled');
        var data = $(this).serialize();
        $.ajax(
            url: 'scripts/email_freeMonth.php',
            type: "post",
            dataType: 'json',
            data: data,
            success: function (data) 
                _self.closest('div').find('button[type="submit"]').removeAttr('disabled');
                if (data.code == false) 
                    _self.closest('div').find('[name="' + data.field + '"]').css('border-bottom', 'solid 2px red');
                    _self.find('.customised-formgroup').last().after('<div class="msg"><p style="color:red;padding:0;font-size:13px;font-weight:bold;position:absolute">*' + data.err + '</p></div>');
                 else 
                    $('.msg').html('<p style="color:green;padding:0;font-size:13px;font-weight:bold;position:absolute">' + data.success + '</p>');
                    _self.find('.customised-formgroup').last().after('<div class="msg"><p style="color:green;padding:0;font-size:13px;font-weight:bold;position:absolute">' + data.success + '</p></div>');
                    _self.closest('div').find('input,textarea').val('');
                
            
        );
        $.ajax(
            url: 'scripts/freemonth_action.php',
            type: "post",
            dataType: 'json',
            data: data,
            success: function (data) 
                _self.closest('div').find('button[type="submit"]').removeAttr('disabled');
                if (data.code == false) 
                    console.log("DATA.CODE == FALSE");
                 else 
                    console.log("DATA.CODE == TRUE");
                
            , 
            error:function(exception)alert('Exception:'+ JSON.stringify(exception));
        );

    );

【问题讨论】:

【参考方案1】:

当您通过 AJAX 请求传递序列化数据时,if(isset($_POST['submit'])) 不会评估为真,因为按钮不是通过请求发送的数据的一部分。您可以改用if($_SERVER['REQUEST_METHOD'] == "POST") 来检查请求是否已提交。只需在您的 PHP 文件中更新它,它应该可以工作!

【讨论】:

我更新了该行,但仍然收到由该行引起的异常警告屏幕:error: function (exception) alert('Exception:' + JSON.stringify(exception)); ,但我仍然收到所有状态响应为 200,这很奇怪。我不确定如何调试 php,因为我无法将错误回显到文档中,因为文档从未真正显示给用户。 @Tom 如果您在 AJAX 请求中取出 dataType: 'json',它是否适用于更新的 PHP 文件?昨天我试图弄清楚时收到了错误响应,但是当未设置 dataType 时它没有触发错误。 我去掉了那一行,现在调用的是成功函数而不是错误函数,这是一个改进!但是我提醒两个ajax调用传递的数据变量,第二个(调用mailchimp api)是空的。我不知道这是否是个问题,因为 api 调用所需的所有数据都应该在 php 文件中,该文件从 html 文件中获取数据 我已更新 script.js 以显示我正在使用的当前 ajax 调用。我还纳入了 headmax 的建议,即在“成功”响应中将一个 AJAX 调用嵌套在另一个中 @Tom 如果您在原始问题中将请求分开,则只需更新 PHP 文件即可。你可以在 script.js 中留下dataType: 'json'【参考方案2】:

我认为你需要在你的第一次调用ajax 下添加第二次调用into。

$('.email_form_freemonth').on('submit', function (e) 
        e.preventDefault();
        var _self = $(this);
        var __selector = _self.closest('input,textarea');
        _self.closest('div').find('input,textarea').removeAttr('style');
        _self.find('.msg').remove();
        _self.closest('div').find('button[type="submit"]').attr('disabled', 'disabled');
        var data = $(this).serialize();
        $.ajax( //WORKS
            url: 'scripts/email_freeMonth.php',
            type: "post",
            dataType: 'json',
            data: data,
            success: function (data) 
                _self.closest('div').find('button[type="submit"]').removeAttr('disabled');
                if (data.code == false) 
                    _self.closest('div').find('[name="' + data.field + '"]').css('border-bottom', 'solid 2px red');
                    _self.find('.customised-formgroup').last().after('<div class="msg"><p style="color:red;padding:0;font-size:13px;font-weight:bold;position:absolute">*' + data.err + '</p></div>');
                 else 
                    $('.msg').html('<p style="color:green;padding:0;font-size:13px;font-weight:bold;position:absolute">' + data.success + '</p>');
                    _self.find('.customised-formgroup').last().after('<div class="msg"><p style="color:green;padding:0;font-size:13px;font-weight:bold;position:absolute">' + data.success + '</p></div>');
                    _self.closest('div').find('input,textarea').val('');
                
            
            
            //because you are under an event submit "form" and you ajax post was after this one
            $.ajax( 
            url: 'scripts/freemonth_action.php',
            type: "post",
            dataType: 'json',
            success: function (data) 
                alert(data);
            
            );
        );

【讨论】:

我不认为你可以在另一个中运行一个 ajax 调用,因为当我尝试你的代码时,我的 IDE 中出现语法错误 阅读这篇文章***.com/questions/10089447/… 我只是告诉你需要在第一个调用下添加调用,因为它是提交的动作触发器,第二个可以在我们处于异步世界的第一个交易结束时调用,但是我们需要事件来调用它(提交,点击,onload ...),第二个函数ajax需要一个匿名函数成功 我尝试按照您提供的链接中的建议将一个 ajax 调用放在另一个调用中,但我仍然遇到同样的错误。所有响应状态均为 200,但 freemonth_action.php 的响应正文为空,应该包含我认为的内容 是的,您需要在第一次调用 ajax 后在页面中找到类名 .msg,因为成功的 ajax 会将一些 html 附加到页面中 $('.msg').html('

' + data.success + '

'); _self.find('.customised-formgroup').last().after('

' + data.success + '

');如果此 html 标记不包含此 .msg 类,则脚本停止告诉我您的错误可能是我可以在线显示一些吗?问候。

以上是关于Mailchimp API 调用使用 AJAX的主要内容,如果未能解决你的问题,请参考以下文章

Mailchimp 如何在 javascript 中调用 mailchimp 3.0 API

使用 mailchimp-api-v3 批量调用不超过 10 个分段成员

MailChimp API DrewM\MailChimp\MailChimp::call() 调用未定义的方法

使用 .Net 调用 MailChimp API v3.0

使用 OAuth 2 令牌调用 MailChimp API

只需一次调用 MailChimp API v3 即可获取所有 mailchimp 活动的详细信息