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

如何退出Next.js v13路由缓存?设置响应头仍缓存的问题

问题:Next.js API路由设置no-store仍被缓存,x-nextjs-cache:HIT与cache-control共存是否违反规范?

我编写了如下route.ts代码:

import { NextResponse } from 'next/server';
import { serializeError } from 'serialize-error';

export const GET = async () => {
  try {
    // ...
  } catch (error) {
    return NextResponse.json({
      error: serializeError(error),
    }, {
      status: 500,
    });
  }

  const response = NextResponse.json({
    status: 'OK',
  });

  response.headers.set('cache-control', 'no-store');
  response.headers.set('x-robots-tag', 'noindex');

  return response;
};

无论我在响应中添加什么头信息,响应始终被缓存。以下是curl请求示例:

curl -v https://...
*   Trying 104.196.232.237:443...
* Connected to ray.run (104.196.232.237) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=ray.run
*  start date: May 27 01:05:38 2023 GMT
*  expire date: Aug 25 01:05:37 2023 GMT
*  subjectAltName: host "ray.run" matched cert's "ray.run"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* h2h3 [:method: GET]
* h2h3 [:path: ...]
* h2h3 [:scheme: https]
* h2h3 [:authority: ray.run]
* h2h3 [user-agent: curl/7.86.0]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x11e811400)
> GET /... HTTP/2
> Host: ray.run
> user-agent: curl/7.86.0
> accept: */*
>
< HTTP/2 200
< x-dns-prefetch-control: on
< x-frame-options: DENY
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< referrer-policy: origin-when-cross-origin
< permissions-policy: camera=(), microphone=(), geolocation=(), interest-cohort=()
< strict-transport-security: max-age=63072000; includeSubDomains; preload
< vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Accept-Encoding
< x-nextjs-cache: HIT
< cache-control: no-store
< content-type: application/json
< x-robots-tag: noindex
< date: Fri, 16 Jun 2023 00:56:58 GMT
< server: railway
<
* Connection #0 to host ray.run left intact

响应中同时出现x-nextjs-cache: HIT和cache-control: no-store,这是否说明Next.js公然无视规范?


解答

这不是Next.js无视HTTP规范,而是要区分Next.js内部缓存机制和HTTP缓存头的不同作用:

  • x-nextjs-cache: HIT是Next.js App Router的内部缓存标识,仅代表它从自身的静态缓存池返回了响应,和HTTP规范没有冲突。
  • cache-control: no-store是正确返回给下游(客户端、CDN等)的HTTP头,作用是禁止这些环节缓存响应,Next.js并没有忽略这个规范——你可以看到响应里确实正确输出了该头。

要解决Next.js内部缓存的问题,你需要显式禁用该API路由的静态优化,因为App Router的API路由默认是静态渲染并缓存的。只需在route.ts顶部添加以下任意一行配置:

// 强制路由为动态,每次请求都重新执行逻辑
export const dynamic = 'force-dynamic';

或者:

// 设置缓存过期时间为0,禁用静态缓存
export const revalidate = 0;

添加后,Next.js会每次请求都重新运行API逻辑,x-nextjs-cache会变为MISS,同时cache-control: no-store依然会正常作用于下游。

另外,也可以直接在创建响应时指定头信息,写法更简洁:

const response = NextResponse.json(
  { status: 'OK' },
  { 
    headers: { 
      'cache-control': 'no-store', 
      'x-robots-tag': 'noindex' 
    } 
  }
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:50:10