在 CodeIgniter 中检查 Ajax 请求
Posted
技术标签:
【中文标题】在 CodeIgniter 中检查 Ajax 请求【英文标题】:Check for Ajax request in CodeIgniter 【发布时间】:2012-07-26 02:17:06 【问题描述】:我在一个 php 脚本中,我想检查请求是否是 Ajax 请求。 (基本上不允许直接脚本访问,除了 Ajax 调用。)
所以,我在 index.php
主文件中的某处定义了 IS_AJAX
:
define('IS_AJAX',
isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
然后在我的脚本顶部检查它:
if (!IS_AJAX) exit('No direct script access allowed');
由于我是 CodeIgniter 的新手,我想知道:
有没有这样的内置功能? 有更优雅的方法吗?【问题讨论】:
【参考方案1】:您可以使用input 类中的$this->input->is_ajax_request()
:
if (!$this->input->is_ajax_request())
exit('No direct script access allowed');
【讨论】:
is_ajax_request() 不是安全措施。有一个类似的答案,而是返回 404,这样可以避免给人一种误导的印象。 (HTTP/1.1“当服务器不希望确切地揭示请求被拒绝的原因或没有其他响应时,通常使用此状态码”)***.com/questions/6555652/… 我一般都是用load的方式来加载文件,如何防止那些文件直接加载呢?【参考方案2】:如果您使用hooks (CI docs),则无需为每个 AJAX 方法添加if (!$this->input->is_ajax_request())
。这是基于此处的Jorge's solution 并进行了一些细微改进:
config/config.php
通过更改默认值启用 CI 挂钩(来自 FALSE
):
$config['enable_hooks'] = TRUE;
config/hooks.php
在末尾添加以下内容:
$hook['post_controller_constructor'] = array(
'class' => 'Ajax_only',
'function' => 'show_404_on_illegal_ajax',
'filename' => 'Ajax_only.php',
'filepath' => 'hooks'
);
post_controller_constructor
:在您的控制器实例化后立即调用,但在任何方法调用发生之前
config/ajax_methods.php
创建一个新的配置文件,其中包含仅应在发出 AJAX 请求时调用的所有控制器和方法:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
|--------------------------------------------------------------------------
| References to all AJAX controllers' methods or the controller itself
|--------------------------------------------------------------------------
|
| Based on Jorge's solution: https://***.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
创建钩子本身,它检测当前控制器和/或其方法是否存在于上面的新配置文件中。如果是这样,当当前请求不是 AJAX 并且方法/控制器在配置中有 truthy 值时,它会显示 404 默认页面:
<?php
defined('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();
【讨论】:
我认为这是在进行大型项目时实现这一概念的更好方法。【参考方案3】:如果您想自定义来自您的 codeigniter 应用的请求,请尝试以下操作: 您必须在 application/hooks 文件夹中创建一个名为 Ajax_only.php 的钩子
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
* ]
* ]
*/
并配置你的 application/config/hooks.php 文件
$hook['post_controller_constructor'] = array(
'class' => 'Ajax_only',
'function' => 'eval_request',
'filename' => 'Ajax_only.php',
'filepath' => 'hooks'
);
【讨论】:
这非常棒 Jorge!从字面上看是一个线路保护程序(不需要在每个方法中都有is_ajax_request()
if
s)。我做了一个few adjustments to your solution and added a few details in a new answer。感谢您的洞察力!
您制作CPHPython是一个很大的进步,谢谢您的发言!以上是关于在 CodeIgniter 中检查 Ajax 请求的主要内容,如果未能解决你的问题,请参考以下文章
如何创建ajax请求以使用DataTable和Codeigniter并在同一文件中返回
使用jQuery AJAX请求CodeIgniter从Controller显示数据库中的数据到View而不刷新页面