Symfony2, check if an action is called by ajax or not

30,395

Solution 1

It's very easy!

Just add $request variable to your method as use. (For each controller)

<?php
namespace YOUR\Bundle\Namespace

use Symfony\Component\HttpFoundation\Request;

class SliderController extends Controller
{

    public function someAction(Request $request)
    {
        if($request->isXmlHttpRequest()) {
            // Do something...
        } else {
            return $this->redirect($this->generateUrl('your_route'));
        }
    }

}

If you want to do that automatically, you have to define a kernel request listener.

Solution 2

For a reusable technique, I use the following from the base template

{# app/Resources/views/layout.html.twig #}
{% extends app.request.xmlHttpRequest 
     ? '::ajax-layout.html.twig'
     : '::full-layout.html.twig' %}

So all your templates extending layout.html.twig can automatically be stripped of all your standard markup when originated from Ajax.

Source

Solution 3

First of all, note that getRequest() is deprecated, so get the request through an argument in your action methods.

If you dont want to polute your controller class with the additional code, a solution is to write an event listener which is a service.

You can define it like this:

services:
    acme.request.listener:
        class: Acme\Bundle\NewBundle\EventListener\RequestListener
        arguments: [@request_stack]
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onRequestAction }

Then in the RequestListener class, make a onRequestAction() method and inject request stack through the constrcutor. Inside onRequestAction(), you can get controller name like this:

$this->requestStack->getCurrentRequest()->get('_controller');

It will return the controller name and action (I think they are separated by :). Parse the string and check if it is the right controller. And if it is, also check it is XmlHttpRequest like this:

$this->requestStack->getCurrentRequest()->isXmlHttpRequest();

If it is not, you can redirect/forward.

Also note, that this will be checked upon every single request. If you check those things directly in one of your controllers, you will have a more light-weight solution.

Share:
30,395
Clément Andraud
Author by

Clément Andraud

I'm a wonderful dev !

Updated on April 26, 2020

Comments

  • Clément Andraud
    Clément Andraud about 4 years

    I need, for each action in my controller, check if these actions are called by an ajax request or not.

    If yes, nothing append, if no, i need to redirect to the home page.

    I have just find if($this->getRequest()->isXmlHttpRequest()), but i need to add this verification on each action..

    Do you know a better way ?

  • Yes Barry
    Yes Barry over 7 years
    Nice, clever idea. I like it :3
  • rebru
    rebru almost 5 years
    I say the same, nice, clever idea ;-)