CakePHP ajax帖子不断返回400 Bad Request

kSe*_*udo 5 jquery post cakephp

我想在动作中使用ajax帖子.GET请求工作正常但是当我尝试POST时,我在firebug中看到'400 Bad Request'并且视图返回'Black hole'响应.

这是Jquery请求:

            $.ajax({
            url:"/usermgmt/users/editUser",
            type:"POST",
            success:function(data) {
                alert('Wow this actually worked');
                //ko.applyBindings(self);

            },
            error:function() {
                alert('This will never work');
            }
        });
Run Code Online (Sandbox Code Playgroud)

这是由于Cake的安全设置还是我在这里缺少的?

Jos*_*eph 18

防止形式篡改是安全组件提供的基本功能之一.只要启用它,它就会将所有POST视为表单提交.

常规的手工编码HTML表单不能与启用的安全组件一起使用,因此JQuery生成的POST也不会.当然,您可以使用$this->Security->validatePost = false;或者$this->Security->csrfCheck = false;然后放弃安全组件提供的保护.

要使安全组件保持正常运行,您需要使用CakePHP表单助手创建您要通过ajax发布的表单.通过这种方式,data[_Token][fields]data[_Token][unlocked]隐藏字段得到与他们的密钥生成:

<?php 
    echo $this->Form->create('Test',array('id'=>'testform'));
    echo $this->Form->input('Something');
    echo $this->Form->submit();
    echo $this->Form->end();
?> 
Run Code Online (Sandbox Code Playgroud)

这将生成如下内容:

<form action="/your/url" id="testform" method="post" accept-charset="utf-8">
    <div style="display:none;">
        <input type="hidden" name="_method" value="POST"/>
        <input type="hidden" name="data[_Token][key]" value="9704aa0281d8b5a2fcf628e9fe6f6c8410d8f07a" id="Token937294161"/>
    </div>
    <div class="input text">
        <input name="data[Test][Something]" class="required" type="text" id="TestSomething"/>
    </div>
    <div class="submit">
        <input  type="submit" />
    </div>
    <div style="display:none;">
        <input type="hidden" name="data[_Token][fields]" value="0c81fda1883cf8f8b8ab39eb15d355eabcfee7a9%3A" id="TokenFields817327064"/>
        <input type="hidden" name="data[_Token][unlocked]" value="" id="TokenUnlocked281911782"/>
    </div>
</form>   
Run Code Online (Sandbox Code Playgroud)

现在只需要在JQuery中序列化这个表单,就可以使用ajax POST发送它:

    $('#testform').submit(function(event) {
        $.ajax({
            type: 'POST',
            url: "/your/url",
            data: $('#testform').serialize(),
            success: function(data){ 
                alert('Wow this actually worked');
            },
            error:function() {
                alert('This will never work');
            }
        });
        event.preventDefault(); // Stops form being submitted in traditional way
    });
Run Code Online (Sandbox Code Playgroud)

现在,如果按下提交按钮,POST将成功.

重要提示:由于表单助手的令牌只能与安全组件一起使用,因此只有每打算生成一次POST时,此解决方案才有效.如果您需要能够在页面重新加载之间多次发布相同的表单,那么当您在Controller的开头添加安全组件时,您需要执行以下操作:

public $components = array(
    'Security' => array(
        'csrfUseOnce' => false
    )
);
Run Code Online (Sandbox Code Playgroud)

...这将允许令牌用于多个请求.它不是那么安全,但你可以将它与它结合起来,csrfExpires以便令牌最终到期.这一切都记录在Cake书CSRF配置部分.

  • 只是想添加一点,因为如果javascript修改了一个'隐藏'输入字段,也会发现错误,因为令牌会记录这些错误.如果您不想禁用validatePost,只需将字段从隐藏字段更改为文本类型字段,然后通过css(display:none)隐藏它们.这将允许您的表单正确提交,即使javascript更改您的输入字段. (2认同)