CakePHP4 - 使用 Ajax 创建记录

CakePHP4 - Create Record with Ajax

我是 CakePHP 的新手,我花了很多时间试图弄清楚如何添加一个可以 post 到不同数据库 table 的表单 ajax。基本上,我有一个可以执行搜索的表单,但在用户执行搜索之前,我需要捕获他的电子邮件和其他一些字段,并将它们存储在我的数据库中单独的 table 中。

虽然我已经能够设置表单并将数据发送到控制器,但我无法克服错误 400/错误请求。我不确定是不是因为我 post url 设置错误(已启用:$this->loadComponent('FormProtection');

任何帮助或方向将不胜感激!!我还没弄明白,也许我处理问题的方式不对,或者我应该使用 post link(如果可能的话)。

我目前的设置:

index.php => website.com/app/services:

<div id="user_basics"> 
<?= $this->Form->create() ?>
<fieldset>
    <legend><?= __('Add Visitor') ?></legend>
    <?php
        echo $this->Form->control('name');
        echo $this->Form->control('email');
        echo $this->Form->control('city');
    ?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>

jQuery: 
$('#user_basics form').submit(function(event) {
    
var ajaxdata = $("#user_basics form").serializeArray();

event.preventDefault();

    $.ajax({
        url:"<?= $this->Url->build(["controller" => "visitors","action" => "addExternal"]); ?>",
        type:"POST",
        headers: $('[name="_csrfToken"]').val(),
        data:ajaxdata,
        dataType: "json",
        success:function(response) {
            console.log(response);
            console.log("success");
        },
        error: function(response) {
            console.error(response.message, response.title);
            console.log("nope");
        }
    });

});

我没有将控制器文件包含在 addExternal 操作中。

注意:我指的是访客控制器,我相信这是解决此问题的正确方法 - 将用户数据发送到已经设置为连接到数据库的访客控制器)

所以通过日志,我发现 csfr / formprotection 不能同时使用,而且可能还有其他一些错误。这是现在有效的方法,不过我很好奇这是否是最佳路线。

我有 2 tables,服务和访客。在服务索引上,我需要能够在访问者 table 中创建一条记录(我将在其中存储用户的 email/data 以允许他们进行搜索)。

访客控制器:

public function initialize(): void {
        parent::initialize();
        $this->loadComponent('RequestHandler');   
        $this->loadComponent('FormProtection');
    }
    public function beforeFilter(EventInterface $event){
        parent::beforeFilter($event);
        $this->FormProtection->setConfig('unlockedActions', ['userinfo']);
    }

    public function userinfo(){
        // $this->autoRender = false;
        if ($this->request->is('ajax')) {
            $this->response = $this->response->withDisabledCache();
        }
        
        $visitor = $this->Visitors->newEmptyEntity();
        if ($this->request->is('post')) {
            $visitor = $this->Visitors->patchEntity($visitor, $this->request->getData());

            if ($this->Visitors->save($visitor)) {}
        }
        $this->set(compact('visitor')); 
    } 

访客指数:

<div id="user_basics"> 
<?= $this->Form->create() ?>

<fieldset>
    <legend><?= __('Add Visitor') ?></legend>
    <?php
        echo $this->Form->control('name');
        echo $this->Form->control('email');
        echo $this->Form->control('city');
    ?>
</fieldset>
<?= $this->Form->button(__('ok')) ?>
<?= $this->Form->end() ?>
</div>

<script>
$(document).ready(function () {
    
    
    $('#user_basics form').submit(function(event){
        
        var $form = $(this);
        var $target = $('div.response');
        var csrf = $('input[name=_csrfToken]', $form).val();
        var data =  $(this).serialize();

        $.ajax({
            method: "POST",
            url: "http://dev.cts.cl/app/visitors/userinfo/",
            beforeSend: function(xhr) {
                xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
                xhr.setRequestHeader('X-CSRF-Token', csrf);
            },
            data: data,
            dataType: "json"
        })
        
        console.log("000-o");

        event.preventDefault();
    }); 
});
</script>

我很不高兴我不得不关闭表单安全,我希望我能找到正确的方法。我也想 return 来自我的控制器 class 的响应,但也没有弄清楚(根据我在网上找到的错误 500)。

一个简单的错误

var ajaxdata = $("#user_basics form").serializeArray();

您正在尝试从具有“user_basics 表单”的表单序列化数组。 这里的id“user_basic”可能有多种形式。 所以最好用 id

创建表单
<?= $this->Form->create(null,[
           'id'=>'user_basic_form',
    ]) ?>
var ajaxdata = $("#user_basic_form").serializeArray();