CakePHP4 ajax提交报`_Token` was not found in request data
问题根因
这个报错和你配置的CSRF令牌没关系,是FormProtectionComponent(CakePHP自带的表单防篡改组件)拦截的请求。你现在的解锁配置没生效,核心原因两个:
- 配置时机不对:FormProtection组件在控制器启动阶段就会执行校验,如果你把
unlockedActions的配置写在beforeFilter或者具体的动作方法里,配置加载的时候校验已经跑完了,根本不生效。 - 看错误日志里实际被拦截的请求路径是
/blog/carregar,要确认你配置的解锁动作确实覆盖了实际请求的接口,别配错了动作名。
修复步骤
1. 把解锁配置移到正确的位置
不要动态在后续逻辑里设置解锁动作,要么在AppController加载组件的时候直接全局配,要么在对应控制器的initialize()方法里配置,保证配置在组件校验执行前加载。
全局配置方式(修改src/Controller/AppController.php):
// 把原来的加载代码 // $this->loadComponent('FormProtection'); // 替换成初始化时直接传入解锁配置 $this->loadComponent('FormProtection', [ 'unlockedActions' => ['carregar', 'filtrar'] ]);
如果只想在Blog控制器里解锁,就写到BlogController的initialize()方法里:
// src/Controller/BlogController.php public function initialize(): void { parent::initialize(); $this->FormProtection->setConfig('unlockedActions', ['carregar', 'filtrar']); }
2. 可选:单动作临时关闭校验
如果这两个接口不需要做表单防篡改校验,也可以直接在对应动作方法开头关闭校验,简单直接:
public function filtrar() { $this->FormProtection->setConfig('validate', false); // 剩下的筛选逻辑正常写 } public function carregar() { $this->FormProtection->setConfig('validate', false); // 剩下的加载逻辑正常写 }
3. 补个小坑
你前端ajax里写的是相对路径blog/filtrar,很容易因为当前页面路径不对匹配错路由,建议改成CakePHP生成的绝对路径,避免请求跑到别的动作去:
$.ajax({ // 替换原来的相对路径 url: '<?= $this->Url->build(['controller' => 'Blog', 'action' => 'filtrar']) ?>', type: 'post', headers: { 'X-CSRF-Token': csrfToken, }, // 其余配置不变 })
你之前写的CSRF令牌注入、请求头携带逻辑都是对的,radio的
hiddenField => false配置也不影响安全校验,不用改。
内容的提问来源于stack exchange,提问作者Rafael Laste
相关产品推荐
相关产品推荐

