Urql+Codegen调用GraphQL login mutation报POST body missing错误
问题排查与解决方案
核心原因定位
你遇到的POST body missing报错90%以上是Apollo Server 3+默认开启的CSRF防护机制和urql请求头不匹配导致的,你的原生fetch手动加了Content-Type: application/json头符合校验规则所以能成功,urql请求大概率缺失了该请求头触发了Apollo的拦截。另外你提到的单参数简单mutation能成功,是因为短query被urql默认转为GET请求,不需要校验POST body所以绕过了限制。
分步排查解决
1. 优先修复urql客户端配置(推荐,不降低服务端安全性)
在urql初始化时显式配置请求头,确保所有请求都带Content-Type: application/json:
import { createClient, defaultExchanges } from 'urql'; const client = createClient({ url: 'http://localhost:4000/graphql', exchanges: defaultExchanges, // 新增fetchOptions配置 fetchOptions: () => { return { headers: { 'Content-Type': 'application/json', // 如果有全局授权头也可以在这里统一加 // 'Authorization': `bearer ${token}` }, }; }, });
2. 临时关闭服务端CSRF校验(仅测试环境用)
如果本地调试不想改客户端,可以在Apollo Server初始化时关闭CSRF防护:
import { ApolloServer } from 'apollo-server-express'; const server = new ApolloServer({ typeDefs, resolvers, // 新增配置关闭CSRF校验,生产环境不要开 csrfPrevention: false, });
3. 辅助排查手段
如果上述方法无效,按以下步骤确认请求差异:
- 打开Chrome网络面板,对比urql发送的login请求和原生成功请求的差异:
- 确认请求方法为POST
- 确认请求头存在
Content-Type: application/json - 确认请求体是合法JSON,包含
query和variables字段
- 打印urql返回的
CombinedError的完整响应内容,确认服务端返回的具体报错:if (error) { console.log(await error.networkError.response.text()) } - 排查是否有自定义urql exchange修改了请求头/请求体,或者Express服务端在Apollo中间件之前加了异常的body解析中间件,把请求body提前消费了。
内容的提问来源于stack exchange,提问作者AndrogenAgonist
相关产品推荐
相关产品推荐

