Is it possible to restrict a route for AJAX only?
PhpAjaxSymfonyPhp Problem Overview
Is it possible to restrict a Symfony 2 route for XHR requests only? I want to declare routes, which are only accessible via AJAX.
I do not want to put some extra lines into each AJAX-specific-actions like that:
if ($request->isXmlHttpRequest()) {
// do something
} else {
// do something else
}
I want to define:
- one rule for AJAX requests
- one rule for GET/POST requests to the same URL
in order to get around having conditions like above.
Php Solutions
Solution 1 - Php
I know this question is a bit older but meanwhile a new way to achieve this was introduced in Symfony 2.4.
For an ajax restriction it would look like this:
contact:
path: /contact
defaults: { _controller: AcmeDemoBundle:Main:contact }
condition: "request.isXmlHttpRequest()"
Also possible in Annotation:
/**
* ContactAction
*
* @Route("/contact", name="contact", condition="request.isXmlHttpRequest()")
*/
Solution 2 - Php
My advice would be to define your own router service instead of default, which would extend from Symfony\Bundle\FrameworkBundle\Routing\Router
, and redefine method resolveParameters() with implementing your own logic for handling additional requirements.
And then, you could do something like this in your routing:
your_route:
pattern: /somepattern
defaults: { somedefaults }
requirements:
_request_type: some_requirement
Solution 3 - Php
I'm not sure that you can prevent the request taking place, however you can check for an XHR request in the Controller by checking the current Request
The code would look like this:
if ($request->isXmlHttpRequest()) {
// ...
}
This is not 100% reliable, due to among other things, browser inconsistencies and the possibility of proxy interference. However it is the predominant method of checking for an asynchronous request and is recommended by many. If you are cr
URL Parameter
An alternative would be to add a parameter in your URL to identify the request as asynchronous. This is achieved by adding ?ajax=1
to your URL. Then, check for the parameter with:
$AjaxRequest = $request->getParameter('ajax');
If($AjaxRequest == 1) {
//...
}
Of course, at this point you could also create a specific Route e.g. /ajax/index/
.
Solution 4 - Php
No, you cannot. It is not depend on which framework you are using, AJAX requests basically are just requests to a server. There is no 100% reliable solution, just "hacks".
Solution 5 - Php
What you're looking for does not exist in Symfony routing configuration.
Request::isXmlHttpRequest is even not 100% reliable, and checks HTTP headers put by your JavaScript library :
> It works if your JavaScript library set an X-Requested-With HTTP header. It is known to work with Prototype, Mootools, jQuery.
Solution 6 - Php
You can use the requirements for reach the described result.
So, suppose that you're defining routes onto yml format, you have to do something like this
my_route:
pattern: /path/to/route
defaults: { _controller: CompanyBundle:Controller:Action, _format: html }
requirements:
_format: xmlhttp /* not sure about the correct format because
i've never checked about */
And you can, of course, use _method: POST
or _method: GET