这个问题可以通过在Apollo Client的links中添加一个错误链接来解决。当刷新token过期时,错误链接将被调用,并且我们可以使用它来执行所需的操作。以下是解决此问题的示例代码:
import { ApolloLink, Observable } from "apollo-link";
import { onError } from "apollo-link-error";
import { setContext } from "apollo-link-context";
import { HttpLink } from "apollo-link-http";
import { withClientState } from "apollo-link-state";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
import Token from "./utils/token";
const httpLink = new HttpLink({
uri: "graphql_server_url"
});
const authLink = setContext(async (req, { headers }) => {
const token = await Token.load();
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : ""
}
};
});
const errorLink = onError(({ response, graphQLErrors, networkError }) => {
if (graphQLErrors && graphQLErrors.some(isUnauthorizedError)) {
Token.delete(); // 清除旧令牌
window.location.replace("/login"); // 重定向到登录页
}
});
const defaultOptions = {
watchQuery: {
fetchPolicy: "cache-and-network",
errorPolicy: "all"
},
query: {
fetchPolicy: "cache-and-network",
errorPolicy: "all"
}
};
const cache = new InMemoryCache();
const stateLink = withClientState({cache});
const links = ApolloLink.from([
stateLink,
errorLink,
authLink,
httpLink
]);
const apolloClient = new ApolloClient({
link: links,
cache: cache,
defaultOptions: defaultOptions
});
function isUnauthorizedError(error) {
const { extensions } = error;
const { code } = extensions || {};
return code === "UNAUTHENTICATED";
}
export default apolloClient;
在代码中,我们添加了一个错误链接(errorLink),该链接将在遇到GraphQL错误时执行。具体而言,我们检查GraphQLErrors中是否有UNAUTHENTICATED
代码的错误,如果是,则清除旧令牌并重定向到登录页面。当links中的其余链接(authLink和httpLink)使用时,我们确保在请求头中包含有效的令牌。最后,我们导出一个初始化的Apollo客户端实例(