Check for Ajax request in CodeIgniter
You can use $this->input->is_ajax_request()
from the input class:
if (!$this->input->is_ajax_request()) { exit('No direct script access allowed');}
There is no need to add an if (!$this->input->is_ajax_request())
to every AJAX method if you use hooks (CI docs). This is based on Jorge's solution in here with a few slight improvements:
config/config.php
Enable CI hooks by changing the default value (from FALSE
):
$config['enable_hooks'] = TRUE;
config/hooks.php
Add the following at the end:
$hook['post_controller_constructor'] = array( 'class' => 'Ajax_only', 'function' => 'show_404_on_illegal_ajax', 'filename' => 'Ajax_only.php', 'filepath' => 'hooks');
post_controller_constructor
: called immediately after your controller is instantiated, but prior to any method calls happening
config/ajax_methods.php
Create a new config file with all the controllers and methods that should only be invoked when an AJAX request is made:
<?phpdefined('BASEPATH') OR exit('No direct script access allowed');/*|--------------------------------------------------------------------------| References to all AJAX controllers' methods or the controller itself|--------------------------------------------------------------------------|| Based on Jorge's solution: https://stackoverflow.com/a/43484330/6225838| Key: controller name| Possible values:| - array: method name as key and boolean as value (TRUE => IS_AJAX)| - boolean: TRUE if all the controller's methods are for AJAX requests|*/$config['welcome'] = [ 'index' => FALSE, // or 0 -> this line can be removed (just for reference) 'ajax_request_method_1' => TRUE, // or 1 'ajax_request_method_2' => TRUE, // or 1];$config['ajax_troller'] = TRUE;
hooks/Ajax_only.php
Create the hook itself, which detects if the current controller and/or its methods are present on the new config file above. If so, it shows the 404 default page when the current request is not AJAX and the method/controller has a truthy value in the config:
<?phpdefined('BASEPATH') OR exit('No direct script access allowed');class Ajax_only { public function __construct() { $this->CI = &get_instance(); $this->CI->config->load('ajax_methods'); } public function show_404_on_illegal_ajax() { $fetched_troller_val = $this->CI->config->item( $this->CI->router->fetch_class() ); $fetched_method = $this->CI->router->fetch_method(); $is_ajax_method = is_array($fetched_troller_val) && // verify if the method's name is present isset($fetched_troller_val[$fetched_method]) && // verify if the value is truthy $fetched_troller_val[$fetched_method]; // if the controller is not in the config file then // config->item() returned NULL if($fetched_troller_val !== NULL && $this->CI->input->is_ajax_request() === FALSE && ($fetched_troller_val === TRUE || $is_ajax_method) ) { show_404(); } }}
if you want customize the requests from your codeigniter app, try this:You must create a hook named Ajax_only.php in application/hooks folder
class Ajax_only { private $_controllers = []; private $CI; public function __construct() { $this->CI =& get_instance(); } public function eval_request() { $controller = $this->CI->router->fetch_class(); $method = $this->CI->router->fetch_method(); if ( array_key_exists( $controller, $this->_controllers ) && $this->CI->input->is_ajax_request() === FALSE ) { if ( ( $this->_controllers[ $controller ] === TRUE || ( is_array( $this->_controllers[ $controller ] ) && array_key_exists( $method, $this->_controllers[ $controller ] ) && $this->_controllers[ $controller ][ $method ] === TRUE ) ) ) { show_404(); } } }}/*Examples * $_controllers = [ * 'my_controller_name' => TRUE //all methods must be ajax * 'my_controller_name => [ * 'method_name' => TRUE //only the selected methods must be ajax * ] * ] */
And configure your application/config/hooks.php file
$hook['post_controller_constructor'] = array( 'class' => 'Ajax_only', 'function' => 'eval_request', 'filename' => 'Ajax_only.php', 'filepath' => 'hooks');