GraphQL:无法读取 Apollo 客户端中的响应标头

Posted

技术标签:

【中文标题】GraphQL:无法读取 Apollo 客户端中的响应标头【英文标题】:GraphQL: Cannot read response headers in Apollo Client 【发布时间】:2019-07-26 04:11:30 【问题描述】:

我想用 Apollo Client 读取响应头,但我不能。

我正在使用 Apollo 服务器和 Apollo 客户端进行 GraphQL API 通信,我想来回发送标头。我已经设置了客户端,以便它发送一个 x-client-version 标头,并且我已经将服务器设置为有时也使用相同的标头进行回复。

问题是,当我尝试使用 Apollo 客户端读取 x-client-version 标头(或任何标头)时,我得到未定义。根据我在网上找到的示例,甚至 YouTube 演练,我在下面设置了一些 Afterware:

const clientVersionAfterware = new ApolloLink((operation, forward) =>
  forward(operation).map(response => 
    const 
      response:  headers ,
     = operation.getContext();
    console.log(headers);
    if (headers) 
      const token = headers.get("x-client-version");
      console.log(token);
      if (token) 
        localStorage.setItem("clientVersion", token);
      
    

    return response;
  ),
);

将其附加到链接链上:

    const httpLink = handleErrors.concat(
  clientVersionAfterware.concat(new HttpLink(linkOptions)),
);
const batchHttpLink = handleErrors.concat(
  clientVersionAfterware.concat(
    new BatchHttpLink( ...linkOptions, batchInterval: 10 ),
  ),
);

最终在 ApolloClient 构造函数中连接链接:

new ApolloClient(
    link: split(
      ( operationName = "" ) => operationName.startsWith("findOrCreate"),
      httpLink,
      batchHttpLink,
    ),
    cache,
    ...opts,
  );

我听说 headers 对象是空白的,但仍然可以读取 headers,但根据我的经验,这绝对不是真的。我可以看到服务器确实返回了我希望读取的 x-client-version 标头:

我认为升级我的软件包可能会有所帮助,但他们没有。我正在使用的版本:

"apollo-cache-inmemory": "^1.5.1",
"apollo-client": "^2.5.1",
"apollo-link-batch-http": "^1.2.4",
"apollo-link-error": "^1.1.2",
"apollo-link-http": "^1.5.11",

我有什么遗漏吗?提前致谢!

【问题讨论】:

【参考方案1】:

我在 /graphql 端点上缺少 Access-Control-Expose-Headers

  app.use((req, res, next) => 
    res.append("x-version-backend", `$BUILD_VERSION`);
    res.append("Access-Control-Expose-Headers", "x-version-backend");
    next();
  );

之后我可以看到我的标题:

const responseLogger = new ApolloLink((operation, forward) => 
    return forward(operation).map(result => 
      const headers = operation.getContext().response.headers;
      const backendVersion = headers.get("x-version-backend");
      console.info(`x-version-backend:$backendVersion`);
      return result;
    );
  );

【讨论】:

【参考方案2】:

我想通了。

原来更新 apollo-client 是不够的。我升级了以下包,现在填充了 headers 对象:

"apollo-link-batch-http": "^1.2.9",
"apollo-link-error": "^1.1.8",
"apollo-link-http": "^1.5.12",

我确定你不需要更新 apollo-link-error,但其他两个应该就足够了(尤其是 apollo-link-http)。

【讨论】:

以上是关于GraphQL:无法读取 Apollo 客户端中的响应标头的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Apollo Graphql 客户端和 React 解决“TypeError:无法读取未定义的属性“参数”?

将对象数组添加到突变 react-graphql-apollo-mongoose 时,“无法读取未定义的属性 'get'”

ReactJS/Javascript/Graphql/React-apollo:无法读取未定义的属性“正在加载”

APOLLO CLIENT - 突变不起作用(无法读取未定义的属性“数据”)

GraphQL / Apollo - 无法获取 NetworkError

无法读取未定义的属性“findOne” - Vue.js、Apollo Server、GraphQL 错误