首页 > 解决方案 > CakePHP 3:发送jQuery-Tabledit的Ajax Post请求时出现禁止错误

问题描述

尝试在我的表上实现 jQuery-Tabledit ( https://markcell.github.io/jquery-tabledit/ ) 时出现 403 Forbidden Error。经过研究,似乎问题与授权有关,但我不知道如何解决。我既不使用 AuthComponent 也不使用 SecurityComponent。

模板/用户/index.ctp

<div class="user index large-9 medium-8 columns content">
    <h3><?= __('User') ?></h3>
    <table id="table" cellpadding="0" cellspacing="0">
        <thead>
            <tr>
                <th scope="col">Id</th>
                <th scope="col">Name</th>
                <th scope="col">Email</th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($user as $user): ?>
            <tr>
                <td><?= $this->Number->format($user->id) ?></td>
                <td><?= h($user->name) ?></td>
                <td><?= h($user->email) ?></td>
            </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
</div>

<?= $this->Html->script('/js/table_edit_test') ?>

webroot/js/table_edit_test.js

$(document).ready(function(){
    $('#table').Tabledit({
        url:"/user/testing",
        columns: {
            identifier: [0, 'id'],
            editable: [[1, 'name'], 
            [2, 'email']]
        },

        onSuccess: function(data, textStatus, jqXHR) {
            console.log('onSuccess(data, textStatus, jqXHR)');
            console.log(data);
            console.log(textStatus);
            console.log(jqXHR);
        },

        onFail: function(jqXHR, textStatus, errorThrown) {
            console.log('onFail(jqXHR, textStatus, errorThrown)');
            console.log(jqXHR);
            console.log(textStatus);
            console.log(errorThrown);
        },

        onAjax: function(action, serialize) {
            console.log('onAjax(action, serialize)');
            console.log(action);
            console.log(serialize);
        },
    });
});

用户控制器.php

public function index() {
    $user = $this->paginate($this->User);

    $this->set(compact('user'));
}

public function testing() {
    $this->autoRender = false;
    if($this->request->is('Ajax')) {
        $input = filter_input_array(INPUT_POST);

        if($input["action"] === 'edit') {
            $user = $this->User->get($input["id"]);
            $user->name = $input["name"];
            $user->email = $input["email"];
            $this->User->save($user);
        }

        return json_encode($input);
    }
}

应用控制器.php

public function initialize() {
    parent::initialize();

    $this->loadComponent('RequestHandler', [
        'enableBeforeRedirect' => false,
    ]);
    $this->loadComponent('Flash');

    /*
     * Enable the following component for recommended CakePHP security settings.
     * see https://book.cakephp.org/3.0/en/controllers/components/security.html
     */
    //$this->loadComponent('Security');
}

调试截图: 安慰

调试器

任何帮助,将不胜感激。

标签: javascriptjqueryajaxcakephpcakephp-3.0

解决方案


403 错误来自 CSRF-Token,即使您没有选择使用该组件,它也会在 CakePHP 3.6 及更高版本中自动添加。感谢 502_Geek 帮助我找出原因。我的修复:

  • src/Template/Layout/default.ctp中:添加标题
<head>
<!--Get CSRF-Token -->
<meta name="csrf-token" content="<?= $this->request->getParam('_csrfToken') ?>" />
</head>
  • webroot/js/jquery.tabledit.js:更改$.post()$.ajax()添加 CSRF-Token 到标题:
var jqXHR = $.ajax({
    type: "POST",
    url: settings.url,
    headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
    data: serialize,
    success: function(data, textStatus, jqXHR) {

        if (action === settings.buttons.edit.action) {
            $lastEditedRow.removeClass(settings.dangerClass).addClass(settings.warningClass);
            setTimeout(function() {
                //$lastEditedRow.removeClass(settings.warningClass);
                $table.find('tr.' + settings.warningClass).removeClass(settings.warningClass);
            }, 1400);
        }

        settings.onSuccess(data, textStatus, jqXHR);
    },
    dataType: 'json'
});
  • webroot/js/table_edit_test.js 中:使用 URL 的完整链接:
url: 'https://localhost/user/testing',

任何像我一样开始学习 JavaScript 的新手请注意:

  • F12 -> 控制台:读取 console.log()
  • F12 -> 网络 -> 单击带有错误状态的文件 -> 参数:从 Ajax 读取 $_POST
  • F12 -> 网络 -> 单击带有错误状态的文件 -> 响应:读取错误的主要原因(CSRF 不匹配,找不到对象等)

推荐阅读