【问题标题】:CodeIgniter + jQuery UI autocomplete = 500 internal server error (with code) due to CSRF set to TRUE由于 CSRF 设置为 TRUE,CodeIgniter + jQuery UI 自动完成 = 500 内部服务器错误(带代码)
【发布时间】:2011-07-18 08:22:36
【问题描述】:

查看代码如下:

<html>
<head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>

        <!-- Load JQuery UI -->
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script type="text/javascript">
    $( function() {    

        $("#input").autocomplete({
            source: function(req, add){
                $.ajax({
                    url: '<?php echo base_url(); ?>test/ac2',
                    dataType: 'json',
                    type: 'POST',
                    //data: req,
                    data: 'input='+req,
                    success: function(data){
                        if(data.response =='true'){
                           add(data.message);
                        }
                    }
                });
        },
        minLength: 2,
        select: function(event, ui){
            $(this).end().val(ui.item.value);
            }
        });

     });      
</script>
</head>
<?php

echo form_open();
echo form_input('input', '', 'id="input"');
echo form_close();

?>
</html>

和控制器代码:

class Test extends CI_Controller {

    function index()
    {
        $this->load->view('vw/test_vw');
    }

    public function ac2()
    {

        //$search = $this->input->post('term');
              $search = $this->input->post('input');

        $data['response'] = 'false';

        $this->db->select('*');
        $this->db->from('loc_exercise');
        $this->db->like('locations', $search);
        $locations = $this->db->get()->result();


        if (count($locations) > 0) {
            $data['message'] = array();

            foreach ($locations as $location) {
                $data['message'][] = array(  'label' => $location->locations,
                'item'  => $location->locations,
                'value' => $location->locations );
            }

            $data['response'] = 'true';
        }
        echo json_encode($data);
    }

当我在输入框中输入任何内容时,我会在控制台上看到:

POST http://my.example.com/test/ac2 500 (Internal Server Error)

在 CI 错误日志上似乎没有问题(log_threshold 为 1,/logs 为 chmod 777)。

顺便说一句,我的 config.php 中 query_strings 为 TRUE,allow_get_array 为 TRUE。

任何想法如何解决这个问题?

【问题讨论】:

    标签: php jquery codeigniter csrf


    【解决方案1】:

    您的问题中没有任何内容表明您需要打开query_stringsallow_get_array

    试试这个

    注释掉这一行

    $search = $this->input->post('term');
    

    然后将$search 作为第一个参数添加到您的函数中

    public function ac2($search)
    

    然后尝试用浏览器点击 URL

    http://yourdomain.com/index.php/test/ac2/&lt;insert your search string here&gt;

    现在我们知道您的网址很好

    换回你的控制器。

    试试这个...

    data: 'term='+req,  //<-- change to this
    

    【讨论】:

    • 是的!这样做可以正常工作并将 JSON 数据返回到浏览器并获得不错的匹配 - 但是当我回到我以前的设置时,我仍然在控制台上得到 500 - 我如何让它按预期工作(即,匹配显示为下面的下拉列表输入)?
    • FWIW -- 如果我回到之前的设置(我上面的原始代码)并导航到 http://yourdomain.com/index.php/test/ac2/ 我会从数据库中获取所有结果的 JSON 数据
    • 感谢您提供帮助 - 不幸的是,它不起作用,仍然得到 500 - 我从 OP 更新了代码 - 你会看到现在我使用 input 作为发布键,因为这是上面的名称表单输入——我还简化了foreach array 并添加了你的 JS 建议——但它仍然不起作用,我不知道为什么!
    • 非常感谢您的帮助——看起来问题是 CSRF 令牌开启,见下文——干杯
    【解决方案2】:

    在没有 AJAX 的情况下检查您的 PHP 代码。您的错误表明您的 PHP 是导致错误的原因。

    还有一件事,在致电-&gt;result()之前先看看是否有结果会更好

    【讨论】:

      【解决方案3】:

      这几乎可以肯定是 CSRF 令牌问题。

      this in the CI forums 和这个blog post

      【讨论】:

      • 你搞定了——只要我关闭 CSRF,自动完成下拉菜单就会正常工作——现在我想知道我将如何使用 CSRF... 仍然没有消化提供的解决方案在 CI 论坛上的那篇文章中:P - 无论如何,非常感谢!
      • @coolgeek 上面提到的博客文章很棒,很好地解释了如何解决这个问题
      【解决方案4】:

      您似乎缺少发送带有 POST 数据的 csrf 令牌,请尝试:

          $("#input").autocomplete({
              source: function(req, add){
      
          var cct = $("input[name=ci_csrf_token]").val(); //  <---
      
                  $.ajax({
                      url: '<?php echo base_url(); ?>test/ac2',
                      dataType: 'json',
                      type: 'POST',
                      //data: req,
                      data: 'input='+req,
          'ci_csrf_token': cct,   //  <---
                      success: function(data){
                          if(data.response =='true'){
                             add(data.message);
                          }
                      }
                  });
          },
          minLength: 2,
          select: function(event, ui){
              $(this).end().val(ui.item.value);
              }
          });
      
       }); 
      

      您还可以找到类似的令牌:

           csrf_test_name:$("input[name=csrf_test_name]").val(),
      

      当使用表单助手并打开它时,该标记会在视图中生成:

        <?php echo form_open();?>
      

      来源: * http://codeigniter.com/forums/viewthread/176318/ **自己头疼

      【讨论】:

        猜你喜欢
        • 2015-08-01
        • 1970-01-01
        • 2013-06-02
        • 1970-01-01
        • 1970-01-01
        • 2016-02-13
        • 2014-09-22
        • 2015-04-14
        • 1970-01-01
        相关资源
        最近更新 更多