30

I'm building application with angularjs and laravel 4. Everything is fine but I need now to allow only XHR requests.

This is what I have at the beginning of my controller. But this statement is always false.

    if (!\Request::ajax())
    {
        return Response::json(array('halt'=>Request::ajax()));
    };

In angular I'm using standard $http service.

angular.module('APP')
.factory("API", ($http,$q,appClient,apiURL) ->
 class FB
  constructor:->
    this.deferredData = $q.defer();
  info: (reload)->
    $http(
      method: "get"
      url: apiURL+'game/'+appClient+"/info"
    ).success((res)->
      dostuff()
    )
zajca
  • 2,288
  • 4
  • 30
  • 40
  • 1
    [Check this answer](http://stackoverflow.com/questions/20166320/laravel-4-ajax-check-to-include-xmlhttprequest-from-magnific-popup/20167599#20167599). – The Alpha Dec 09 '13 at 16:26
  • 1
    Usually there a header set by most browsers when doing an AJAX call: `X-Requested-With: XMLHTTPRequest`. Do you see that header from the browser inspector? – UltraInstinct Dec 09 '13 at 17:03
  • 6
    Thank's a lot I have to set: `$httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"` – zajca Dec 09 '13 at 17:47

3 Answers3

40

When doing AJAX calls, the X-Requested-With header is often set to XMLHttpRequest. Laravel's Request::ajax() method is built on top of a Symfony2 method that simply checks for the presence of this header.

In October 2012, Angular.js removed this header because they felt that it was rarely used.

As @Thrustmaster and yourself mentioned in the comments, you need to set:

$httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"
Moshe Katz
  • 15,992
  • 7
  • 69
  • 116
  • Yes, I know that this question is very old. This answer is just to get it out of the "unanswered questions" list - that's why it is community wiki. – Moshe Katz Jul 25 '14 at 04:06
23

If you'd rather not modify the front-end angular application (or can't), and would rather modify your Laravel code to differentiate between Angular JS AJAX requests vs. other requests, you can also use Request::wantsJson():

if(Request::wantsJson()) {
    // Client wants JSON returned 
} else {
    // Client does not want JSON returned
}

The wantsJson method relies on the standard Accepts HTTP header (rather than the non-standard X-Requested-With header) for the presence of application/json. As long as Angular JS leaves that in by default and you don't remove it on purpose, this method should be reliable.

Jeff Lambert
  • 24,395
  • 4
  • 69
  • 96
  • 1
    Perfect. Just what I was looking for. – skovmand Sep 22 '15 at 18:06
  • 2
    Adding my 2 cents - this answer will help in some cases but will not help in others e.g when angular loads template files (router, directives, etc) - although technically done via ajax, Laravel `Request::wantsJson()` will not intercept it. The accepted answer by Moshe is IMOH a better way to verify that all requests are handled correctly. Regardless, on Laravel's side you should always check for `if (Request::isAjax() || Request::wantsJson()) {}`. – dev7 Apr 06 '17 at 19:55
14

For AngularJs newbies looking for where to add $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"

Here is an example:

var angularApp = angular
  .module('angularApp', [
    'ngResource',
  ])
  .config(['$httpProvider', function($httpProvider) {
      $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
  }]);
Emeka Mbah
  • 16,745
  • 10
  • 77
  • 96