【问题标题】:Apollo Link response headersApollo Link 响应标头
【发布时间】:2018-05-06 17:34:44
【问题描述】:

我在一个简单的 React 应用程序中使用最新版本的 Apollo Client,我试图从响应中提取一个标头值,用于显示返回的记录集的大小。

我很欣赏这不是提供结果集大小的最优雅的方式,但这就是当前设置 API 的方式。

我希望使用中间件类型选项来执行此操作,但是当我检查响应对象时,我似乎无法提取任何标题。

网络跟踪确实显示响应标头符合预期,因此我怀疑我误解了如何获取所需的底层对象。

我检查了文档,但没有什么比这更明显,因此这里的问题...

【问题讨论】:

    标签: apollo-client


    【解决方案1】:

    在这里找到答案:https://github.com/apollographql/apollo-client/issues/2514

    必须通过操作上下文访问它...有趣的是,开发工具似乎显示 headers 对象是空的,但是您可以从中提取命名的标头...

    const afterwareLink = new ApolloLink((operation, forward) => {
      return forward(operation).map(response => {
        const context = operation.getContext();
        const { response: { headers } } = context;
        
        if (headers) {
          const yourHeader = headers.get('yourHeader');
        }
        
        return response;
      });
    });
    

    【讨论】:

    • 我使用的是相同的代码,但我仍然收到null:github.com/apollographql/apollo-client/issues/… 知道有什么问题吗?
    • 有人知道为什么开发工具显示 headers 对象为空吗??
    • @K-Sato 是的,标头是延迟加载的,即它们仅在您第一次访问时加载。尝试拨打headers.lazyInit();,他们会神奇地出现
    • 如果使用 CORS,您需要将标头添加到服务器返回的 Access-Control-Expose-Headersgithub.com/apollographql/apollo-client/issues/… 否则您只会得到内容长度和类型等信息。
    【解决方案2】:

    当后端响应时,headers 应该包括:

    Access-Control-Expose-Headers: * // 或者你的 refreshToken 字段的名称

    这里有完整的代码:

    前端:(Apollo & React)

    const httpLink = new HttpLink({ uri: URL_SERVER_GRAPHQL })
    
    // Setup the header for the request
    const middlewareAuthLink = new ApolloLink((operation, forward) => {
      const token = localStorage.getItem(AUTH_TOKEN)
    
      const authorizationHeader = token ? `Bearer ${token}` : null
      operation.setContext({
        headers: {
          authorization: authorizationHeader
        }
      })
      return forward(operation)
    })
    
    // After the backend responds, we take the refreshToken from headers if it exists, and save it in the cookie.
    const afterwareLink = new ApolloLink((operation, forward) => {
      return forward(operation).map(response => {
        const context = operation.getContext()
        const { response: { headers } } = context
    
        if (headers) {
          const refreshToken = headers.get('refreshToken')
          if (refreshToken) {
            localStorage.setItem(AUTH_TOKEN, refreshToken)
          }
        }
    
        return response
      })
    })
    
    const client = new ApolloClient({
      link: from([middlewareAuthLink, afterwareLink, httpLink]),
      cache: new InMemoryCache()
    })
    

    在后端(快递)。 如果我们需要刷新令牌(例如:因为实际令牌即将过期)

    const refreshToken = getNewToken()
    res.set({
      'Access-Control-Expose-Headers': 'refreshToken', // The frontEnd can read refreshToken
      refreshToken
    })
    

    文档来自:https://www.apollographql.com/docs/react/networking/network-layer/#afterware

    【讨论】:

    • 我想知道是否有办法获取标头并将其放入响应中。也许在某种包装对象中?
    • 不错。谢谢。终于找到万恶之源
    猜你喜欢
    • 2019-03-08
    • 2018-02-25
    • 2018-02-14
    • 2019-07-26
    • 2021-09-28
    • 1970-01-01
    • 2020-03-29
    • 2019-04-01
    • 2019-07-26
    相关资源
    最近更新 更多