php 在 CodeIgniter 中检查 Ajax 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11687180/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 01:52:29  来源:igfitidea点击:

Check for Ajax request in CodeIgniter

phpajaxcodeigniter

提问by Dr.Kameleon

I'm in a PHP script and I want to check whether the request is an Ajax request. (Basically to NOT allow direct script access, other than Ajax calls.)

我在一个 PHP 脚本中,我想检查请求是否是 Ajax 请求。(基本上不允许直接脚本访问,除了 Ajax 调用。)

So, I'm defining IS_AJAXsomewhere in the main index.phpfile:

所以,我IS_AJAX在主index.php文件中的某个地方定义:

define('IS_AJAX', 
       isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 
       strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');

And then checking it at the top of my script:

然后在我的脚本顶部检查它:

if (!IS_AJAX) exit('No direct script access allowed');

Since I'm new to CodeIgniter, I would like to know:

由于我是 CodeIgniter 的新手,我想知道:

  • Is there any such built-in functionality?
  • Is there a more elegant way to do it?
  • 有没有这样的内置功能?
  • 有没有更优雅的方法来做到这一点?

回答by Yan Berk

You can use $this->input->is_ajax_request()from the inputclass:

您可以$this->input->is_ajax_request()输入类使用:

if (!$this->input->is_ajax_request()) {
   exit('No direct script access allowed');
}

回答by CPHPython

There is no need to add an if (!$this->input->is_ajax_request())to every AJAX methodif you use hooks (CI docs). This is based on Jorge's solutionin here with a few slight improvements:

如果您使用hooks (CI docs),无需if (!$this->input->is_ajax_request())为每个 AJAX 方法添加一个。这是基于Jorge的解决方案在这里有一些细微的改进:

config/config.php

config/config.php

Enable CI hooks by changing the default value (from FALSE):

通过更改默认值(从FALSE)启用 CI 挂钩:

$config['enable_hooks'] = TRUE;

config/hooks.php

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

post_controller_constructor: 在您的控制器实例化后立即调用,但在任何方法调用发生之前

config/ajax_methods.php

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:

使用所有控制器和方法创建一个新的配置文件,这些控制器和方法应该只在发出 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://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

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 truthyvalue in the config:

创建钩子本身,它检测当前控制器和/或其方法是否存在于上面的新配置文件中。如果是这样,当当前请求不是 AJAX 并且方法/控制器在配置中有一个值时,它会显示 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();
    }
  }
}

回答by Jorge Andrés

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

如果您想自定义来自您的 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
 *      ]
 * ]
 */

And configure your application/config/hooks.php file

并配置您的 application/config/hooks.php 文件

$hook['post_controller_constructor'] = array(
    'class' => 'Ajax_only',
    'function' => 'eval_request',
    'filename' => 'Ajax_only.php',
    'filepath' => 'hooks'
);