使用Apollo Client查询Django后端时出现400 Bad Request错误求助
Apollo Client查询Django后端时出现400 Bad Request错误求助
看起来你遇到的问题大概率是mode: "no-cors"这个设置搞的鬼——这个模式会让浏览器刻意限制请求的内容和响应的可读性,直接导致后端无法正确解析你的GraphQL查询,返回400错误。咱们一步步来解决:
第一步:立刻移除客户端的no-cors配置
把Apollo Client里的fetchOptions: { mode: "no-cors" }删掉,这个设置完全不适合GraphQL请求场景,只会帮倒忙。
第二步:用Django官方推荐的方式处理CORS
不要依赖csrf_exempt来绕开跨域问题,正确的做法是使用django-cors-headers包:
- 安装依赖:
pip install django-cors-headers
- 在Django的
settings.py里配置:
# 添加到INSTALLED_APPS INSTALLED_APPS = [ ... 'corsheaders', ... ] # 添加中间件(注意顺序,CorsMiddleware要放在CommonMiddleware前面) MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... ] # 开发环境可以暂时允许所有源,生产环境一定要指定具体的前端域名 CORS_ALLOW_ALL_ORIGINS = True # 如果你需要携带cookie(比如CSRF验证),还要加上这个 CORS_ALLOW_CREDENTIALS = True
第三步:修正Apollo Client的配置
确保你的客户端配置正确指向后端GraphQL地址,并且如果需要携带凭证的话加上credentials选项:
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'; import { onError } from '@apollo/client/link/error'; // 替换成你的后端GraphQL接口地址,比如http://localhost:8000/graphql const httpLink = createHttpLink({ uri: 'http://your-django-backend-url/graphql', // 如果后端需要CSRF验证,加上这个 credentials: 'include', }); const errorLink = onError(({ graphQLErrors, networkError }) => { if (graphQLErrors) { graphQLErrors.forEach(({ message, locations, path }) => console.log(`[GraphQL错误]: 消息: ${message}, 位置: ${locations}, 路径: ${path}`) ); } if (networkError) console.log(`[网络错误]: ${networkError}`); }); const client = new ApolloClient({ link: errorLink.concat(httpLink), cache: new InMemoryCache(), }); export default client;
第四步:排查查询本身的问题
虽然Postman和GraphiQL能跑通,但还是要确认:
- 你的查询变量(比如
low、high、start、end)的类型是否和后端Graphene定义的字段类型完全匹配?比如start和end是不是DateTime类型,前端传的ISO格式字符串是否正确? - 打开浏览器的开发者工具→Network标签,找到GraphQL请求,查看
Request Payload是不是完整的查询内容,Response里有没有具体的错误提示(400错误通常会返回详细的错误信息,比console.log更有用)。
最后:别乱用csrf_exempt
除非你明确知道自己在做什么,否则不要给GraphQL视图加csrf_exempt。如果后端启用了CSRF保护,Apollo Client会自动处理cookie的传递,只要你配置了credentials: 'include'并且Django的CORS设置正确。
按照这些步骤调整后,应该就能解决400错误了,如果还有问题,把浏览器Network面板里的请求详情贴出来,能更精准地排查~
备注:内容来源于stack exchange,提问作者Suerg
相关产品推荐
相关产品推荐

