Search code examples
phpajaxcodeigniterhttp-headersfullcalendar-4

How to enable my CodeIgniter controller to correctly identify ajax calls from FullCalendar4?


I am using FullCalendar 4.4.0 with a CodeIgniter application that I am working on.

In many places in my project, I am successfully using CI's $this->input->is_ajax_request() method to determine whether my controller is being loaded by an ajax request or not.

The problem is that when I am using FullCalendar's single-source events option and passing a POST request, the is_ajax_request() call is not identifying the call as coming from ajax.

What can I do to enable my controller to correctly identify ajax calls?


Solution

  • One of the major breaking changes from FullCalendar version 3 to version 4 is

    • Removal of jQuery as a dependency.

    This is relevant because consequently:

    X-Requested-With is set only by AJAX libraries like jQuery, Mootools, Prototype etc.


    CodeIgniter's is_ajax_request() source code looks like this:

    /ci/system/core/input.php:

    /**
     * Is AJAX request?
     *
     * Test to see if a request contains the HTTP_X_REQUESTED_WITH header.
     *
     * @return    bool
     */
    public function is_ajax_request()
    {
      return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
    }
    

    This means a solution can be found a couple of ways...

    1. Hack FullCalendar's /core/main.js file and add:

      Add the following line immediately after the xhr.open() call in the requestJson() method:

      xhr.setRequestHeader('X-Requested-With', 'xmlhttprequest'); /* Food for CI's $this->input->is_ajax_request() */
      
    2. If you are never expecting any $_POST values with a standard page load (this is true of my application), simply do not use is_ajax_request() for this specific task. In your controller, just use this instead:

      if (!empty($_POST)) {
      

      or more simply (because the superglobal will always be declared)

      if ($_POST) {