Sf2:FOS UserBundle:注册 AJAX

Sf2 : FOS UserBundle : registration AJAX

我正在尝试使用 AJAX 注册用户。

我在 FOSUserEvents::REGISTRATION_SUCCESS

上创建了一个事件侦听器

所以我想知道是否已发出 AJAX 请求,但我客户端的响应并不令我满意。

这里是我的事件侦听器,请注意发送的响应是一个测试,所以当然不应该有 "else" 条件。

<?php

namespace SE\AppBundle\EventListener;

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Ajax listener on FOS UserBundle registration
 */
class RegistrationListener implements EventSubscriberInterface
{
    private $router;

    public function __construct(RequestStack $RequestStack)
    {
        $this->requestStack = $RequestStack;
    }

    /**
     * {@inheritDoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess'
        );
    }

    public function onRegistrationSuccess()
    {

        $request = $this->requestStack->getCurrentRequest();

        if ($request->isXmlHttpRequest()) {

            $array = array( 'success' => true ); // data to return via JSON
            $response = new Response( json_encode( $array ) );
            $response->headers->set( 'Content-Type', 'application/json' );

            return $response;

        }
        else{
            $array = array( 'success' => false ); // data to return via JSON
            $response = new Response( json_encode( $array ) );
            $response->headers->set( 'Content-Type', 'application/json' );

            return $response;
        }
    }
}

services.yml:

se.app.listener.registration:
    class: SE\AppBundle\EventListener\RegistrationListener
    arguments: ["@request_stack"]
    tags:
        - { name: kernel.event_subscriber }

javascript:

// Submit the request
$.ajax({
    type        : 'POST',
    url         : url,
    data        : data,
    success     : function(data, status, object) {

        console.log('success');
        console.log(data);

    },
    error: function(data, status, object){
        console.log('error');
        console.log(data);
    }
});

首先,奇怪的是它进入了错误状态。

注册成功页面DOM返回console.log(数据):

...
<p>Congrats brieuc.tribouillet7777@gmail.com, your account is now activated.</p> 
...

那么这个逻辑应该在这里还是我应该覆盖控制器?我做错了什么?

由于 REGISTRATION_SUCCESS 事件的级别,您无法 return 直接来自 EventListener 的响应。

您需要获取 FormEvent 并修改其响应。
让我们将其作为参数传递:

class RegistrationListener implements EventSubscriberInterface
{
    // ...

    public function onRegistrationSuccess(FormEvent $event)
    {
        $request = $this->requestStack->getCurrentRequest();

        // Prepare your response
        if ($request->isXmlHttpRequest()) {
            $array = array( 'success' => true ); // data to return via JSON
            $response = new Response( json_encode( $array ) );
            $response->headers->set( 'Content-Type', 'application/json' );
        } else {
            $array = array( 'success' => false ); // data to return via JSON
            $response = new Response( json_encode( $array ) );
            $response->headers->set( 'Content-Type', 'application/json' );
        }

        // Send it
        $event->setResponse($response);
    }
}

它应该可以工作。

注意此事件存在无法修改响应的问题。
如果出现问题,您需要在事件订阅中设置低优先级:

public static function getSubscribedEvents()
{
    return [
        FOSUserEvents::REGISTRATION_SUCCESS => [
            ['onRegistrationSuccess', -10],
        ],
    ];
}

#1799

编辑

注意 您应该使用 JsonResponse 而不是 json_encode 您的数据并手动设置 Content-Type

要获取表单本身及其最终错误,您可以这样做:

public function onRegistrationSuccess(FormEvent $event)
{
    $form = $event->getForm();

    if (count($validationErrors = $form->getErrors()) == 0) {
        return $event->setResponse(new JsonResponse(['success' => true]));
    }

    // There is some errors, prepare a failure response
    $body = [];

    // Add the errors in your response body
    foreach ($validationErrors as $error) {
        $body[] = [
            'property' => $error->getPropertyPath() // The field
            'message'  => $error->getMessage() // The error message
        ];
    }

    // Set the status to Bad Request in order to grab it in front (i.e $.ajax({ ...}).error(...))
    $response = new JsonResponse($body, 400); 
    $event->setResponse($response);
}

但是因为它是成功事件,您可能需要重写该方法本身。