apollo-client 没有响应的标头
Posted
技术标签:
【中文标题】apollo-client 没有响应的标头【英文标题】:apollo-client has no headers in response 【发布时间】:2018-02-25 16:59:09 【问题描述】:我有一个带有 apollo client 的 graphql api 和一个 vue.js 前端,用于从后端请求数据。到目前为止它运行良好。
服务器在我需要的每个响应标头中都使用新的 JWT-Token 进行回答。所以解决方案应该很简单.. afterware 从每个响应中获取新密钥并更新相应的存储条目。 但是 .. 标题是空的。
这里是后件:
apolloClient.networkInterface.useAfter([
applyAfterware( response , next)
if (process.env.NODE_ENV === 'development')
console.log('got new response', response);
if (response.status === 401)
store.commit('logout');
store.commit('routeLogin');
next();
]);
下面是响应的样子:
以下是实际发送的内容:
我错过了什么吗?
更新
我找到了一个similar case in the issue tracker,已通过添加Access-Control-Expose-Headers
解决。所以我将它们添加到我的服务器配置中。现在响应看起来像这样,而 apollos headers 对象仍然是空的:
【问题讨论】:
【参考方案1】:您必须删除 。
来自:
applyAfterware(res, next)
到:
applyAfterware(res, next)
现在您可以获得完整的标头信息。
apolloClient.networkInterface.useAfter([
applyAfterware(res, next)
console.log("response:", res.options.headers);
if (res.response.status === 401)
store.commit('logout');
store.commit('routeLogin');
// logout();
next();
]);
【讨论】:
我在res.options.headers
的请求中看到了我发送的自定义标头。我认为@gordon-freeman 正在寻找响应标头...我看到了同样的问题..
没错。我正在寻找响应标头【参考方案2】:
对于所有寻找获取响应标头的方法的人,这是我的最终解决方案:
import _ from 'lodash';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import ApolloClient from 'apollo-client';
import HttpLink from 'apollo-link-http';
import ApolloLink, from from 'apollo-link';
import onError from 'apollo-link-error';
import InMemoryCache from 'apollo-cache-inmemory';
// import parse from 'graphql'
import Auth from '@/store/api/system/auth';
import store from '@/store';
const ENDPOINT = `$process.env.VUE_APP_API_ENDPOINT$process.env.VUE_APP_API_GRAPHQL_ROUTE`;
const defaultHttpLink = new HttpLink( uri: `$ENDPOINTdefault` );
const adminHttpLink = new HttpLink( uri: `$ENDPOINTadmin` );
const authMiddleware = new ApolloLink((operation, forward) =>
// add the authorization to the headers
let authorization = null;
if (Auth.getToken('mimic'))
authorization = `Bearer $Auth.getToken('mimic')`;
else if (Auth.getToken())
authorization = `Bearer $Auth.getToken()`;
operation.setContext(
headers: authorization
);
return forward(operation).map(response =>
const context = operation.getContext();
const
response: headers
= context;
if (headers)
const token = headers.get('Authorization');
if (token)
const jwt = token.split('Bearer');
if (jwt.length)
const token = _.compact(jwt)[0].trim();
// console.log('fresh token: ', token);
// refresh correct token
let name = 'token';
if (Auth.getToken('mimic')) name = 'mimic';
store.commit('auth/addTokenToState', token, name );
return response;
);
);
const networkErrorLink = onError(( response, networkError, operation, forward ) =>
if (networkError)
switch (networkError.statusCode)
case 503:
const message = _.get(networkError, 'result.message');
store.commit('updateMaintenanceState', message || true);
response.errors = null;
break;
case 404:
// TODO
// wenn ein menü angefragt wird, das nicht da ist ...
break;
case 401:
case 403:
case 422:
store.dispatch('auth/signout');
break;
return forward(operation);
);
export const defaultClient = new ApolloClient(
link: from([networkErrorLink, defaultHttpLink]),
cache: new InMemoryCache(),
connectToDevTools: process.env.NODE_ENV === 'development'
);
export const adminClient = new ApolloClient(
link: from([authMiddleware, networkErrorLink, adminHttpLink]),
cache: new InMemoryCache(),
connectToDevTools: process.env.NODE_ENV === 'development'
);
const apolloProvider = new VueApollo(
clients:
default: defaultClient,
admin: adminClient
,
defaultClient
);
Vue.use(VueApollo);
export default apolloProvider;
注意!您需要在服务器端公开标头(您想要获取)。
【讨论】:
以上是关于apollo-client 没有响应的标头的主要内容,如果未能解决你的问题,请参考以下文章
AWS API Gateway 429 响应 - 没有 CORS 标头