使用sendBeacon后收到400 BadRequest错误,求助排查
排查sendBeacon请求400 Bad Request的方向
结合你的代码和问题描述,即使注释控制器逻辑仍返回400,说明请求大概率在到达你的控制器代码之前就被拦截了,按以下顺序排查:
1. 检查CSRF令牌验证
从代码里的FrontendUser、Response类来看,你使用的框架(大概率是Symfony或Contao)可能启用了CSRF保护中间件。sendBeacon发送的请求如果没有携带CSRF令牌,会被框架直接拦截返回400,根本不会进入你的控制器逻辑。
解决方式:把CSRF令牌加入FormData,示例如下(根据框架实际令牌获取方式调整):
var data = new FormData(); data.append('pageid', '{{page::id}}'); data.append('userid', uid); data.append('language', '{{page::language}}'); data.append('_token', '{{csrf_token()}}'); navigator.sendBeacon('/time/', data);
2. 验证路由配置
确认/time/路由是否满足以下条件:
- 允许POST请求,部分框架默认路由仅支持GET,需显式指定
methods: ['POST'] - 接受
multipart/form-data类型的请求体 - 没有前置的参数校验规则(比如强制要求某参数非空)
3. 检查请求参数的实际值
打开开发者控制台的Network面板,查看该请求的Request Payload:
- 确认
pageid、language这些模板变量是否正确渲染,有没有空值或非法格式 - 检查
userid是否为有效值,避免传递undefined或空字符串
4. 查看服务器端日志
直接查看服务器或框架的错误日志(如Nginx的error.log、框架自带的日志文件),里面会有400错误的具体原因,比如:
- "CSRF token is invalid or missing"
- "Required parameter 'pageid' is missing"
这些信息能直接定位问题根源。
5. 明确sendBeacon的请求特性
注意:navigator.sendBeacon()返回true仅表示浏览器成功将请求加入发送队列,不代表服务器处理成功。如果框架需要自定义请求头(比如Authorization),sendBeacon无法满足,可改用fetch结合keepalive选项替代,但优先排查前面的问题。
你的代码参考
前端Beacon代码:
var data = new FormData(); data.append('pageid', '{{page::id}}'); data.append('userid', uid); data.append('language', '{{page::language}}'); navigator.sendBeacon('/time/', data);
控制器代码:
$user = $this->security->getUser(); // Check if user is authenticated if($user instanceof FrontendUser && $_SERVER['REQUEST_METHOD'] === 'POST') { // Query $sql = '...'; // Execute Query $result = $this->connection->fetchAssociative($sql); $objResponse = new Response($sql); } else { // Redirect return new RedirectResponse(\Controller::replaceInsertTags('{{page::language}}') . '/'); } return $objResponse;
内容的提问来源于stack exchange,提问作者Hans Martin
相关产品推荐
相关产品推荐

