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

Next 13中如何让Urql GraphQL服务端组件每次请求都获取数据?

解决Next.js 13服务端组件中Urql请求不触发每次请求的问题

问题分析

你的AccountPage作为App Router下的服务端组件,默认会被Next.js静态优化缓存,导致getViewer只执行一次;同时Next.js对fetch有内置缓存机制,即使Urql设置了requestPolicy: 'network-only',也可能被Next.js的缓存拦截,无法触发每次请求的后端逻辑。

解决方案

1. 强制服务端组件动态渲染

在/app/account/page.tsx中添加动态渲染配置,禁用静态缓存:

const AccountPage = async () => {
    const username = await getViewer();

    return <AccountView username={username} />;
};

// 强制每次请求都重新渲染组件,禁用静态生成缓存
export const dynamic = 'force-dynamic';

dynamic: 'force-dynamic'会让组件在每次请求时都在服务端重新执行,而不是复用之前生成的静态结果。

2. 配置Urql适配Next.js fetch缓存规则

修改query函数,在fetchOptions中添加Next.js专属的缓存控制选项,确保请求不被Next.js缓存:

import { Client, TypedDocumentNode, createClient } from 'urql/core';

const query = async <
    TResponse,
    TVariables extends { [prop: string]: any } = Record<string, unknown>
>(
    queryString: string | DocumentNode | TypedDocumentNode,
    {
        variables,
        client,
        cache
    }: { variables?: TVariables; client?: Client; cache?: RequestCache } = {}
) =>
    await (
        client ??
        createClient({
            url: `/api/graphql`,
            fetchOptions: {
                cache: cache ?? 'no-store',
                // 告诉Next.js禁用该请求的缓存,强制每次走网络
                next: { revalidate: 0 }
            },
            requestPolicy: 'network-only',
            fetch
        })
    )
        .query<TResponse>(queryString, variables)
        .toPromise();

Next.js的next.revalidate: 0会完全禁用该fetch请求的缓存,配合cache: 'no-store'双重确保请求不会被缓存。

3. 后端API禁用缓存响应头

在你的GraphQL API(/pages/api/graphql.ts)中添加响应头,防止浏览器或CDN缓存API结果:

const apolloServer = new ApolloServer({
    schema,
    context: ({ req, res }) => {
        // 设置响应头禁用所有缓存
        res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
        res.setHeader('Pragma', 'no-cache');
        res.setHeader('Expires', '0');
        return { req, res };
    }
});

这一步可以避免API响应被下游缓存系统拦截,确保每次请求都能触发后端的viewer resolver。

验证

完成以上配置后,每次导航到/account页面,查看后端控制台是否输出Hitting the viewer endpoint!,如果每次请求都能看到该日志,说明配置生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:50:22