You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用docker network时apollo-client报GET/HEAD请求不能含body错误如何解决

问题根因分析
  • 错误Request with GET/HEAD method cannot have body的本质是:你的Apollo客户端默认对查询类请求使用GET方法,但是请求头里携带了和请求体相关的字段(比如content-length、content-type),底层HTTP客户端判定该请求存在请求体,触发GET方法不能携带请求体的规范限制。
  • 非Docker网络地址正常的原因:外部地址通常经过Nginx等反向代理,会自动清理无效的请求体相关头,而Docker内部网络直接调用目标服务时没有这层处理,错误被直接抛出。
  • 你的代码中直接全量展开...req.headers是核心诱因:这里的req通常是服务端渲染场景下的上游用户请求对象,包含大量不属于你要发往Apollo服务的请求头,其中就包含触发错误的请求体相关字段。
  • 原有代码还存在多处语法错误,也可能导致运行时的非预期行为。
修复方案

按以下步骤修改即可在保留Docker网络配置的前提下解决问题:

  1. 清理透传的请求头,仅保留必要的授权字段,不要全量展开上游请求的headers
  2. 强制Apollo客户端所有请求使用POST方法,从根源避免GET请求的限制
  3. 修复原有代码中的语法错误

修复后的完整代码如下:

import { ApolloClient, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { createUploadLink } from 'apollo-upload-client';

const authLink = req => {
  return setContext(_ => {
    return {
      headers: {
        // 仅传递需要的授权头,不全量透传上游请求的headers
        authorization: `Bearer ${req.cookies.token}`,
      },
    };
  });
};

export const client = (req) => {
  const uri = 'http://dockerNetwork:3000';
  return new ApolloClient({
    link: authLink(req).concat(createUploadLink({
      uri: uri,
      // 显式关闭查询用GET的配置
      useGETForQueries: false
    })),
    cache: new InMemoryCache(),
    // 强制所有请求使用POST方法
    defaultOptions: {
      watchQuery: {
        fetchPolicy: 'network-only',
        method: 'POST',
      },
      query: {
        fetchPolicy: 'network-only',
        method: 'POST',
      },
      mutate: {
        method: 'POST',
      }
    }
  });
};

内容的提问来源于stack exchange,提问作者new dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 02:15:08