Angular使用Apollo Client跨域调用GraphQL API遇apollographql-client-name头CORS错误
解决Angular + Apollo GraphQL跨域CORS问题(apollographql-client-name请求头不被允许)
问题原因
Apollo Client 3.x及以上版本默认会自动添加apollographql-client-name和apollographql-client-version两个自定义请求头,用于服务端标识客户端信息。这两个头会触发浏览器的预检OPTIONS请求,若后端CORS配置的Access-Control-Allow-Headers未包含这两个头,就会出现跨域拦截错误。
前端解决方案
方案1:禁用Apollo客户端标识头发送
直接在Apollo Client配置中关闭sendUplinkIdentifiers选项,阻止自动添加这两个请求头:
import { ApolloModule, APOLLO_NAMED_OPTIONS } from 'apollo-angular'; import { ApolloClientOptions, InMemoryCache } from '@apollo/client/core'; import { HttpLink } from 'apollo-angular/http'; export function createNamedApollo(httpLink: HttpLink): Record<string, ApolloClientOptions<any>> { return { clientInfo: { name: 'clientInfo', link: httpLink.create({ uri: dashboardUrl, withCredentials: true }), cache: new InMemoryCache({ addTypename: false }), version: '3.4.17', // 添加默认选项,禁用客户端标识头发送 defaultOptions: { watchQuery: { sendUplinkIdentifiers: false, }, query: { sendUplinkIdentifiers: false, }, mutate: { sendUplinkIdentifiers: false, }, }, }, }; } @NgModule({ exports: [ApolloModule], providers: [ { provide: APOLLO_NAMED_OPTIONS, deps: [HttpLink], useFactory: createNamedApollo } ], }) export class GraphQLModule {}
方案2:通过请求拦截器移除指定头
如果方案1未生效,可通过ApolloLink拦截请求,手动移除这两个自定义头:
import { ApolloModule, APOLLO_NAMED_OPTIONS } from 'apollo-angular'; import { ApolloClientOptions, InMemoryCache, ApolloLink } from '@apollo/client/core'; import { HttpLink } from 'apollo-angular/http'; export function createNamedApollo(httpLink: HttpLink): Record<string, ApolloClientOptions<any>> { // 创建拦截器移除指定请求头 const removeCustomHeaders = new ApolloLink((operation, forward) => { operation.setContext(({ headers = {} }) => ({ headers: { ...headers, 'apollographql-client-name': undefined, 'apollographql-client-version': undefined, }, })); return forward(operation); }); // 组合拦截器与HTTP链接 const combinedLink = removeCustomHeaders.concat(httpLink.create({ uri: dashboardUrl, withCredentials: true })); return { clientInfo: { name: 'clientInfo', link: combinedLink, cache: new InMemoryCache({ addTypename: false }), version: '3.4.17', }, }; } @NgModule({ exports: [ApolloModule], providers: [ { provide: APOLLO_NAMED_OPTIONS, deps: [HttpLink], useFactory: createNamedApollo } ], }) export class GraphQLModule {}
内容的提问来源于stack exchange,提问作者Ashok
相关产品推荐
相关产品推荐

