如何从AJAX提交的表单中获得响应?

Pip*_*000 5 javascript php ajax jquery joomla

我想使用Acymailing Joomla!在example.com/mailer上安装的组件,用于管理example.com非Joomla站点的订阅

在那种情况下,我有简单的脚本

 $(function () {
    $('form').on('submit', function (e) {
      e.preventDefault();
      $.ajax({
        type: 'post',
        url: 'https://example.com/mailer/index.php?option=com_acymailing&ctrl=sub',
        data: $('form').serialize(),
        success: function () {
          swal('Great success!');
        }
      });
    });
  });
Run Code Online (Sandbox Code Playgroud)

和形式

<form class="form-inline" action="https://example.com/mailer/index.php?option=com_acymailing&ctrl=sub" method="post">
    <div class="form-group">
        <label class="sr-only" for="user_name">Email address</label>
        <input id="user_name"   type="text" name="user[name]" value="" class="form-control" placeholder="Email">
    </div>
    <div class="form-group">
        <label class="sr-only" for="user_email">Password</label>
        <input id="user_email"   type="text" name="user[email]" value="" class="form-control" placeholder="Password">
    </div>
    <button type="submit" class="btn btn-default">Sign Up!</button>
    <input type="hidden" name="user[html]" value="1" />
    <input type="hidden" name="acyformname" value="formAcymailing1" />
    <input type="hidden" name="ctrl" value="sub"/>
    <input type="hidden" name="task" value="optin"/>
    <input type="hidden" name="redirect" value="https://example.com"/>
    <input type="hidden" name="option" value="com_acymailing"/>
    <input type="hidden" name="visiblelists" value=""/>
    <input type="hidden" name="hiddenlists" value="1"/>
</form>
Run Code Online (Sandbox Code Playgroud)

一切正常,除了成功,错误状态......

Joomla Acymailing有sub.php文件来处理ajax响应

 if($config->get('subscription_message',1) || $ajax){
        if($allowSubscriptionModifications){
            if($statusAdd == 2){
                if($userClass->confirmationSentSuccess){
                    $msg = 'CONFIRMATION_SENT';
                    $code = 2;
                    $msgtype = 'success';
                }else{
                    $msg = $userClass->confirmationSentError;
                    $code = 7;
                    $msgtype = 'error';
                }
            }else{
                if($insertMessage){
                    $msg = 'SUBSCRIPTION_OK';
                    $code = 3;
                    $msgtype = 'success';
                }elseif($updateMessage){

                    $msg = 'SUBSCRIPTION_UPDATED_OK';
                    $code = 4;
                    $msgtype = 'success';
                }else{
                    $msg = 'ALREADY_SUBSCRIBED';
                    $code = 5;
                    $msgtype = 'success';
                }
            }
        }else{
            if($modifySubscriptionSuccess){
                $msg = 'IDENTIFICATION_SENT';
                $code = 6;
                $msgtype = 'warning';
            }else{
                $msg = $modifySubscriptionError;
                $code = 8;
                $msgtype = 'error';
            }
        }

        if($msg == strtoupper($msg)){
            $source = acymailing_getVar('cmd', 'acy_source');
            if(strpos($source, 'module_') !== false){
                $moduleId = '_'.strtoupper($source);
                if(acymailing_translation($msg.$moduleId) != $msg.$moduleId) $msg = $msg.$moduleId;
            }
            $msg = acymailing_translation($msg);
        }

        $replace = array();
        $replace['{list:name}'] = '';
        foreach($myuser as $oneProp => $oneVal){
            $replace['{user:'.$oneProp.'}'] = $oneVal;
        }
        $msg = str_replace(array_keys($replace),$replace,$msg);

        if($config->get('redirect_tags', 0) == 1) $redirectUrl = str_replace(array_keys($replace),$replace,$redirectUrl);

        if($ajax){
            $msg = str_replace(array("\n","\r",'"','\\'),array(' ',' ',"'",'\\\\'),$msg);
            echo '{"message":"'.$msg.'","type":"'.($msgtype == 'warning' ? 'success' : $msgtype).'","code":"'.$code.'"}';
        }elseif(empty($redirectUrl)){
            acymailing_enqueueMessage($msg,$msgtype == 'success' ? 'info' : $msgtype);
        }else{
            if(strlen($msg)>0){
                if($msgtype == 'success') acymailing_enqueueMessage($msg);
                elseif($msgtype == 'warning') acymailing_enqueueMessage($msg,'notice');
                else acymailing_enqueueMessage($msg,'error');
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

并且JSON看起来像Joomla一样通过index.php注册到同一个表单?option = com_acymailing&ctrl = sub

 message    Subscribe confirmed
 type   success
 code   3

 {"message":"Subscribe confirmed","type":"success","code":"3"}
Run Code Online (Sandbox Code Playgroud)

问题是:如何在外部提交表单(在example.com页面上)获取提交状态成功,错误,已经下限等?

Nap*_*bit 6

这个简单的改变可能会为你做到:

$(function () {
  $('form').on('submit', function (e) {
    e.preventDefault();
    $.ajax({
        type: 'post',
        url: 'https://example.com/mailer/index.php?option=com_acymailing&ctrl=sub',
        data: $('form').serialize()
      }
    }).done(function (data) {
        swal('Great success!');
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

我个人喜欢:

$.post("https://example.com...", {
    data: $('form').serialize()
}, function(data) {
    swal('Great success!');
});
Run Code Online (Sandbox Code Playgroud)

因为你的结果是JSON,那应该更像是:

$.post("https://example.com...", {
    data: $('form').serialize()
}, function(data) {
    console.log(data); // shows full return object in console
    swal('Great success!');
}, "json");
Run Code Online (Sandbox Code Playgroud)


Abh*_*rma 1

我不觉得你的ajax有问题,我可以从Joomla php代码中看到,每次当你请求joomla URL时,你总是会得到一个response header status code as 200,所以你的javascript总是会落在ajax代码的成功块上,并返回一些json基于消息,当我检查该控制器的 joomla acymaling(joomla 3.8.3 版本 5.8.1)代码时,我看到line number 74他们正在检查请求是否是使用 ajax 发出的,但Access-Control-Allow-Origin在 php 标头中缺失,这将限制您的外部调用所以你可以if用以下方式替换这个条件:

if($ajax){
    @ob_end_clean();
    header("Content-type:text/html; charset=utf-8");
}
Run Code Online (Sandbox Code Playgroud)

if($ajax){
    @ob_end_clean();
    header("Content-type:text/html; charset=utf-8");
    header("Access-Control-Allow-Origin: *");
}
Run Code Online (Sandbox Code Playgroud)

因此也允许来自任何其他域的调用,但请记住,这也可能导致您的 joomla 代码出现漏洞。您还需要更改 HTML 表单并在 HTML 中添加一个隐藏字段:

<input type="hidden" name="ajax" value="1" />
Run Code Online (Sandbox Code Playgroud)

所以允许 joomla 控制器文件的 ajax 请求。

现在,在 ajax 的成功块中,您可以进行如下检查:

success:function(data, status, xhr){
    var json = $.parseJSON(data);
    swal(json.message, json.type);
}
Run Code Online (Sandbox Code Playgroud)

我希望这能帮助您完成您想要的事情,快乐编码。