在 Apollo React 的 onError 中读取响应标头
Posted
技术标签:
【中文标题】在 Apollo React 的 onError 中读取响应标头【英文标题】:Reading response header in onError in Apollo React 【发布时间】:2021-09-28 13:29:05 【问题描述】:在 React Apollo 客户端中,我们配置了一些链接。
const apollo = new ApolloClient(
cache: new InMemoryCache(),
link: from([
onErrorLink,
afterwareLink,
httpLink
])
);
在我们的应用程序中,当会话超时时,我们返回带有200
状态的响应和一些响应标头(timeout: true
)。通过使用这些响应头,我们需要在 UI 上显示一些对话框。响应头也有content-type: text/html
。另请记住,sessions
在我们组织的联邦级别 (SSO) 上维护,我们无法控制响应上下文。
当会话超时并且我们收到来自服务器的响应时,Apollo react client onError
链接会启动,我们尝试访问响应如下。
const context = operation.getContext();
const response = context.response;
const headers = response.headers;
在上面的代码中,context
从来没有response
属性,因此response
是undefined
。因此,我无法访问标头值。
分析
const afterwareLink = new ApolloLink((operation, forward) =>
return forward(operation).map(response =>
const context = operation.getContext();
const response = context.response;
const headers = response.headers;
return response;
)
;
-
我见过出现错误,只有
onError
被解决,afterwareLink
地图功能永远不会触发。
response
只有通过 Apollo 提供的 forward
函数才会填充到 context
中。
在成功的 API 调用中,afterwareLink
映射函数会解析,并且我能够很好地找到所有标题。
Solutions online 类似,但不起作用。
我被难住了。我可以清楚地看到 Dev Tools 和 Fiddler 中的响应标头。它肯定在那里。只是阿波罗不允许我访问它。就我而言,networkError
或 graphQLErrors
没有多大用处。
【问题讨论】:
但我什至不关心响应。我只需要阅读 REST 或 Graph 标准的响应标头。基本上为什么我们不能在 OnError 中访问响应头?我猜这是非常基本的事情。 你不关心这个用例,这就是你没有发布这个问题的原因,我做到了。而在线阅读、在线提问、调试都是“深入挖掘”的一部分。正如我所说,安全发生在联邦层,所以现在不能只要求我的组织开始使用 Graph。只是想看看,我们的应用端现在可以做什么。 【参考方案1】:这是要解决的几个步骤问题。在下面分享我的发现和解决方案。
-
标题
确保来自 API 的响应具有以下标头值。
Access-Control-Allow-Origin: http://uiclient.com
Access-Control-Expose-Headers: *
第一个标头将确保浏览器满意并允许 UI 解析响应。第二个标头将确保 UI 可以读取响应标头。
-
响应内容类型
在我的情况下,响应类型不是 Graph 所期望的,并且无法更改,因为这是来自联邦层 (SSO)。在第三方服务的情况下,其他人可能会遇到同样的问题,401
、403
或其他状态码。
为了解决这个问题,我写了一个简单的自定义获取函数并将其附加到HttpLink
。
const httpFetch = (uri, options) =>
return fetch(uri, options).then(response =>
// ... read headers from response.headers.
if (response.status >= 500) // or handle 400 errors
return Promise.reject(response.status);
return response;
).catch(error =>
return Promise.reject(error);
);
;
const httpLink = new HttpLink(
uri: 'https://serviceapi.com',
fetch: httpFetch
);
-
处理
httpFetch
当您的响应不是 JSON(或 JSON)时,此技术可用于在 Apollo 客户端中读取数据。就我而言,我首先检查了标头,如果标头具有会话超时值,则使用自定义对象解决承诺(因为主要内容将是 HTML)。
以上步骤将主要帮助您自定义 Apollo 中的任何响应。另请注意,我没有编写任何自定义中间件(或链接)来解决此问题。
【讨论】:
'在我们的应用程序中,当会话超时时,我们返回响应为 200 状态'以上是关于在 Apollo React 的 onError 中读取响应标头的主要内容,如果未能解决你的问题,请参考以下文章
如何从 apollo-link-error 获取 onError 回调中的 uri?
在 React 和 NodeJS 中未经授权重定向之前刷新令牌
apollo-client, onError, ApolloProvider, client.writeData(localstate)... 当服务器返回 401 时如何处理对用户的身份验证