【问题标题】:CakePHP ajax post keeps returning 400 Bad RequestCakePHP ajax 帖子不断返回 400 Bad Request
【发布时间】:2015-02-25 09:35:47
【问题描述】:

我正在尝试将 ajax 发布到操作中。 GET 请求工作正常,但当我尝试 POST 时,我在 firebug 中看到“400 Bad Request”,并且视图返回“黑洞”响应。

这是 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');
            }
        });

这是由于 Cake 的安全设置还是我在这里遗漏了什么?

【问题讨论】:

  • 我正在调查这个,我很确定它的安全组件在这里阻止了我:book.cakephp.org/2.0/en/core-libraries/components/…
  • 好的,如果我用这个禁用跨站点安全性:$this->Security->csrfCheck = false;它工作......但显然这不是要走的路:)有什么想法吗?
  • 你能把代码贴在/usermgmt/users/editUser中吗
  • 这是几个月前发布的,但以防万一您仍在寻找答案:您实际上是在尝试通过 ajax 请求发布一些数据吗?如果是这样,您能否更新问题以显示数据的外观以及发布方式?

标签: jquery cakephp post


【解决方案1】:

防止表单篡改是安全组件提供的基本功能之一。只要启用它,它就会将所有 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();
?> 

这将生成如下内容:

<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>   

现在只需在 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
    });

现在如果你按下提交按钮,POST 就会成功。

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

public $components = array(
    'Security' => array(
        'csrfUseOnce' => false
    )
);

...这将允许令牌用于多个请求。它不是 as 安全的,但您可以将其与 csrfExpires 结合使用,以便令牌最终过期。这一切都记录在CSRF configuration section of the Cake book 中。

【讨论】:

  • 只是想补充一点,因为如果 javascript 修改了“隐藏”输入字段,也会发现错误,因为令牌会跟踪这些。如果您不想禁用 validatePost,只需将字段从隐藏更改为文本类型字段,然后通过 css 隐藏它们(显示:无)。这将允许您的表单正确提交,即使 javascript 更改了您的输入字段。
  • 非常好的和详细的答案,这帮助我解决了完全相同的问题,我需要一段时间才能弄清楚它是 SecurityComponent。先生,为您 +1!
【解决方案2】:

仅供参考,CakePHP 2.3 及更高版本现在包含仅用于此目的的 unlockedAction,用于您的控制器或 AppController 中的 beforeFilter。

$this->Security->unlockedActions = array('ajaxAction');

发件人:http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#disabling-security-component-for-specific-actions

【讨论】:

    【解决方案3】:

    确保您将函数 editUser 放入:

      public function beforeFilter(){
        parent::beforeFilter()
        $this->Auth->allow('editUser');
        }
    

    在 UsersController 内部,

    问候

    【讨论】:

      【解决方案4】:

      约瑟夫的回答对我来说缺少一个细节。我的表单和 ajax 调用在 index.ctp 中并且正在调用 /controller/edit.ctp 所以我的 $this->Form->create 调用需要添加 'action'=>'/controller/edit'。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-14
        • 2011-09-25
        • 2020-11-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-29
        • 2017-11-30
        相关资源
        最近更新 更多