使用Fetch从React向Symfony 4发送GraphQL请求时请求体为空的问题
解决React Fetch向Symfony 4发送GraphQL请求时服务器接收空请求体的问题
我之前也碰到过几乎一模一样的情况,GraphiQL能正常工作但Fetch请求就是传不到后端,大概率是这几个容易忽略的细节没处理好,给你几个排查和解决的方向:
1. 检查Symfony的CSRF防护设置
Symfony默认会对POST请求启用CSRF防护,但API接口通常不需要这个(或者需要特殊处理)。GraphiQL可能已经自动带上了CSRF令牌,但你的Fetch请求没有,导致Symfony拦截了请求体。
- 临时测试:在
config/packages/security.yaml里,给你的/api路由关闭CSRF防护:
security: firewalls: main: pattern: ^/api csrf_protection: false # 其他原有配置...
- 如果需要保留CSRF防护,要从页面的meta标签里获取令牌,加到Fetch请求的头里:
// 先获取页面里的CSRF令牌(Symfony默认会在base模板里渲染<meta name="csrf-token" content="...">) const csrfToken = document.querySelector('meta[name="csrf-token"]').content; fetch('/api', { method: 'post', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrfToken // 加上CSRF令牌头 }, body: JSON.stringify({ query: "mutation {UpdateActionStatus(input: {actionId: 61, status: TO_DO}) { id }}" // 可以去掉variables: null,没有变量时这个字段可选 }), })
2. 确认Symfony后端正确解析JSON请求体
Symfony不会自动把JSON请求体解析到$request->request参数里,你需要手动读取原始内容并解析:
在你的GraphQL控制器里,先调试看看原始请求内容:
public function index(Request $request) { // 先打印原始请求内容,确认后端有没有收到 error_log($request->getContent()); // 正确解析JSON请求体 $data = json_decode($request->getContent(), true); $query = $data['query'] ?? ''; $variables = $data['variables'] ?? []; // 后续GraphQL处理逻辑... }
别用$request->get('query'),因为那是针对表单编码的请求体,JSON格式的内容不会在这个集合里。
3. 修正Fetch请求的几个小细节
- 去掉
variables: null字段:有些GraphQL服务器对null的variables字段处理有问题,没有变量的话直接省略这个字段即可。 - 调试响应的时候,注意
r.json()是异步的,你的原代码里console.log(r.json())会打印一个Promise,应该改成:
fetch('/api', { /* 你的请求配置 */ }) .then(r => r.json()) .then(data => console.log('响应数据:', data)) .catch(error => console.log('请求错误:', error.message));
- 暂时去掉
credentials: 'include'测试:如果是Cookie相关的问题,先去掉这个配置,确认请求体能不能正常传到后端,之后再按需加回来。
4. 用Symfony Profiler排查请求详情
打开Symfony的Profiler(访问/_profiler),找到你的Fetch请求,查看:
- Request Headers:确认
Content-Type是application/json,且请求头里的其他字段正常。 - Request Content:这里能看到后端实际收到的请求体内容,如果是空的,说明请求发送端有问题;如果有内容,说明是后端解析的问题。
先从这几个方向排查,应该能解决问题。
内容的提问来源于stack exchange,提问作者Zephyr
相关产品推荐
相关产品推荐

