You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在NextJS应用中如何从Apollo Link Context获取Express HTTP请求?

在Next.js中为Apollo Client服务端渲染获取Express Request对象

我来帮你解决这个问题——在Next.js的SSR场景下,要把Express的Request对象传递给Apollo Client的初始化函数,核心就是把req从服务端的上下文里传进去,具体步骤如下:

第一步:修改createApolloClient函数,接收req参数

首先要让你的createApolloClient支持接收req参数,这样服务端渲染时就能把Request对象传进来了:

function createApolloClient(initialState = {}, req = null) {
  const httpLink = new HttpLink({
    uri: `${baseUrl}/graphql`,
    credentials: 'same-origin',
    fetch
  })
  const authLink = setContext((_, prevCtx) => {
    let token = ''
    if (typeof window === 'undefined')
      // 现在可以使用传入的req参数提取服务端Cookie了
      token = getCookieFromServer(authCookieName, req)
    else
      token = getCookieFromBrowser(authCookieName)
    return ({
      headers: {
        'Auth-Token': token
      }
    })
  })
  const client = new ApolloClient({
    ssrMode: typeof window === 'undefined',
    cache: new InMemoryCache().restore(initialState),
    link: authLink.concat(httpLink)
  })
  return client
}

第二步:在服务端上下文里传递req

根据你使用的Next.js页面路由类型,有两种常见的传递方式:

1. 在getServerSideProps中传递req

如果你的页面使用getServerSideProps做服务端渲染,直接从上下文参数里拿到req并传给createApolloClient:

export async function getServerSideProps(context) {
  // 把context.req传入初始化函数
  const apolloClient = createApolloClient({}, context.req);
  
  // 这里可以执行你的GraphQL查询,比如:
  // await apolloClient.query({ query: YOUR_QUERY });

  return {
    props: {
      initialApolloState: apolloClient.cache.extract(),
    },
  };
}

2. 在_app.js的getInitialProps中传递req

如果你的全局_app.js中统一处理Apollo Client的初始化,可以在getInitialProps里从ctx拿到req:

function MyApp({ Component, pageProps, apolloClient }) {
  return (
    <ApolloProvider client={apolloClient}>
      <Component {...pageProps} />
    </ApolloProvider>
  );
}

MyApp.getInitialProps = async ({ Component, ctx }) => {
  // 传入ctx.req初始化Apollo Client
  const apolloClient = createApolloClient({}, ctx.req);
  let pageProps = {};

  if (Component.getInitialProps) {
    pageProps = await Component.getInitialProps(ctx);
  }

  return {
    pageProps,
    apolloClient,
    initialApolloState: apolloClient.cache.extract(),
  };
};

export default MyApp;

针对Next.js 13+ App Router的补充

如果你的项目用的是App Router(Server Components),不需要依赖Express的req对象,可以直接用Next.js提供的headers()函数获取Cookie:

// 定义服务端获取Cookie的函数
function getCookieFromServer(name) {
  const cookieHeader = headers().get('cookie');
  if (!cookieHeader) return '';
  
  // 解析Cookie字符串为键值对
  const cookies = cookieHeader.split(';').reduce((acc, cookie) => {
    const [key, value] = cookie.trim().split('=');
    acc[key] = value;
    return acc;
  }, {});
  
  return cookies[name] || '';
}

// 修改createApolloClient,不再需要req参数
function createApolloClient(initialState = {}) {
  const httpLink = new HttpLink({
    uri: `${baseUrl}/graphql`,
    credentials: 'same-origin',
    fetch
  })
  const authLink = setContext((_, prevCtx) => {
    let token = ''
    if (typeof window === 'undefined')
      token = getCookieFromServer(authCookieName)
    else
      token = getCookieFromBrowser(authCookieName)
    return ({
      headers: {
        'Auth-Token': token
      }
    })
  })
  const client = new ApolloClient({
    ssrMode: typeof window === 'undefined',
    cache: new InMemoryCache().restore(initialState),
    link: authLink.concat(httpLink)
  })
  return client
}

这样在Server Components中初始化Apollo Client时,就能直接获取到服务端的Cookie了。

内容的提问来源于stack exchange,提问作者acmoune

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:55:24