使用 EAS 托管部署缓存

了解缓存在 EAS Hosting 上的工作原理。


使用 API 路由缓存

🌐 Caching with API Routes

API 路由可以返回 Cache-Control 指令,EAS 托管将根据缓存指令的值适当地缓存响应。

🌐 API routes can return Cache-Control directives that will be used by EAS Hosting to cache the response appropriately according to the value of cache directives.

export async function GET(request) { return Response.json({ ... }, { headers: { 'Cache-Control': 'public, max-age=3600' }, }); }

响应中存在的 Cache-Control 指令将被 EAS Hosting 用来按指定方式缓存响应。例如,如果 Response 指定了一个缓存指令,并且 max-age 设置为 1800 秒,则响应将在再次调用 API 路由之前缓存指定的时间。

有关 Cache-Control 指令的更多详细信息,请参阅 MDN 文档

🌐 For more details about Cache-Control directives, refer to the MDN documentation.

Cache-Control 指令

🌐 Cache-Control directives

Cache-Control 头可以作为请求和响应头的一部分发送,并且是一串用逗号分隔的设置。

当请求发送 Cache-Control 头时,它通常会发送一些指令,以限制缓存响应的传递方式。如果它作为响应头发送,则会向 EAS Hosting 指定响应的缓存方式以及通过重新调用 API 路由重新验证的频率。

🌐 When a request sends a Cache-Control header, it typically sends directives that constrain how a cached response may be delivered. If it's sent as a response header, it specifies to EAS Hosting how a response will be cached and how often it will be revalidated by re-invoking an API route.

如果缓存指令接受参数,则指令后面跟等号和参数值,例如 max-age=3600。如果指令不接受参数,则列出时不带值,例如 public

🌐 If a cache directive accepts a parameter, the directive is followed by an equal sign and the parameter's value, for example, max-age=3600. If the directive does not accept a parameter, it's listed without a value, for example, public.

如果传递了多个缓存指令,每个指令之间用逗号分隔,例如 public, max-age=3600

🌐 If multiple cache directives are passed, each is separated from the last by a comma, for example, public, max-age=3600.

可缓存性

🌐 Cacheability

几个响应指令确定缓存的响应是否可以缓存或返回给客户端:

🌐 Several response directives determine whether a cached response may be cached or returned to a client:

  • public — 表示任何缓存(包括 EAS 托管)都可能存储该响应。若未标注,则默认响应不会在多个请求间共享。
  • private — 表示该响应仅针对单个用户,并且只能被浏览器缓存。
  • no-storeno-cache — 表示此响应可能绝不会被缓存或存储。

例如,指定 public, max-age=3600 表示 EAS Hosting(除用户的浏览器外)被允许存储响应 3600 秒。然而,private, max-age=3600 表示只有用户的浏览器可以存储响应 3600 秒,而 EAS Hosting 不会缓存它。

🌐 For example, specifying public, max-age=3600 specifies that EAS Hosting is (additionally to a user's browser) allowed to store the response for 3600 seconds. However, private, max-age=3600 means only the user's browser may store the response for 3600 seconds, while EAS Hosting will not cache it.

对于没有设置 Authorization 头且请求方法为 HEADGET 的请求,响应会自动被视为可公开缓存。

🌐 Responses to requests with no Authorization header set and are either for the HEAD or GET request methods are automatically considered publicly cacheable.

为了区分浏览器和 EAS 托管可能缓存的内容,可以使用 s-maxage 指令。例如,使用 s-maxage=3600 指令响应将允许 EAS 托管缓存响应 3600 秒,而用户的浏览器则根本不会缓存它。

🌐 To differentiate between what a browser and EAS Hosting may cache, the s-maxage directive may be used. For example, responding with the s-maxage=3600 directive will allow EAS Hosting to cache the response for 3600 seconds, while the user's browser won't cache it at all.

标头名称

🌐 Header names

如上所示,Cache-Control 头信息被浏览器和 EAS Hosting 都接受和理解。为了对 EAS Hosting 进行更细粒度的缓存定制,并与用户的浏览器分开,你可以使用 CDN-Cache-Control 头信息进行响应。当使用此头信息时,它会隐式地向你的指令中添加 public,并强制 EAS Hosting 根据你的指令缓存响应。

🌐 As seen above, the Cache-Control header is accepted and understood both by browsers and EAS Hosting. To customize caching for EAS Hosting more granularly, and separately from the user's browser, you can respond with a CDN-Cache-Control header. When this header is used, it implicitly adds public to your directives and forces EAS Hosting to cache the response according to your directives.

export async function GET(request) { return Response.json({ ... }, { headers: { 'Cache-Control': 'no-store', // browsers should never store the response 'CDN-Cache-Control': 'max-age=3600', // EAS Hosting should cache for 3600s }, }); }

到期指令

🌐 Expiration directives

  • max-age 用于指定响应被缓存多长时间后才被认为是过期的
  • s-maxage 用于指示 EAS 托管应缓存响应的时间
  • no-cache 相当于指定最大年龄为零
  • immutable 用于表示响应可以无限期缓存,应该尽可能长时间缓存,并且永远不会被视为过期。

此外,还可以使用两个更新的缓存控制指令来确定响应可以在超过为其指定的 max-age 时间后使用多久。

🌐 Additionally, two newer cache control directives can be used to determine how stale responses may be used for longer than the max-age specified for them.

  • stale-while-revalidate 指定响应的过期时间。在缓存的响应被认为过期之后,它允许在指定时间范围内继续将响应返回给客户端,同时在后台重新验证请求。
    • 例如,max-age=1800, stale-while-revalidate=3600 指定响应被缓存 1800 秒。1800 秒后,如果对该响应发起新的请求,只要请求在 3600 秒内发出,就会返回该响应,同时请求也会在后台发送到你的 API 路由。
  • stale-if-error 指定在底层 API 路由意外失败时返回响应的过期时间。这对于使 API 路由具有容错能力非常有用,并适用于当你的 API 路由因运行时错误崩溃或返回 500502503504 响应状态时。
    • 例如,max-age=1800, stale-if-error=3600 指定响应会缓存 1800 秒。1800 秒后,如果你的 API 路由返回错误,将会向客户端发送过期的缓存响应,而不是错误信息。

请求指令

🌐 Request directives

Cache-Control 头可以作为请求头的一部分发送,并会影响 EAS Hosting 如何选择返回缓存的响应。

  • only-if-cached 只有在缓存中存在时才会返回响应,否则会中止请求并返回 504 响应(带有 must-revalidate 指令)
  • no-storeno-cachemax-age=0 将跳过缓存的响应,并始终强制 EAS Hosting 忽略其请求缓存
  • min-fresh 会跳过过期的缓存响应,如果缓存时间超过指定值。例如,min-fresh=360 会阻止返回缓存响应,如果缓存时间超过 360 秒。

此外,max-stalestale-if-error 可能会作为请求的缓存指令的一部分发送,并限制缓存响应的过期时间。然而,请记住,这并不会覆盖请求被缓存的时间,所以这可能仅用于减少缓存响应可接受的过时程度。

🌐 Additionally, max-stale and stale-if-error may be sent as part of the request's cache directive and limit the stale time of cached responses. However, remember that this doesn't override how long a request is cached, so this may only be used to reduce the amount of acceptable staleness of a cached response.

  • max-stale 指定客户端可以接受缓存响应的最长时间。例如,如果响应是使用 stale-while-revalidate=3600 指令缓存的,请求可以指定 max-stale=1800,以仅接受最大有效期为 1800 秒的陈旧响应(在其过期期内,而不是 max-age)。
  • stale-if-error 可用于自定义接受过期响应的时间段,否则 API 路由可能会返回错误。

对于这两个指令,如果服务器端响应的缓存时间比响应的 max-age 上指定的 max-stalestale-if-error 时间短,那么这些指令将不起作用。

🌐 For both directives, if the server-side response was cached for a shorter amount of time than the specified max-stale or stale-if-error periods on top of the response's max-age, then these directives will do nothing.

请求方法

🌐 Request methods

除了缓存 GETHEAD 请求外,EAS Hosting 还支持缓存 POST 请求。

🌐 In addition to caching GET and HEAD requests, EAS Hosting also supports caching POST requests.

如果发送了一个请求体小于1MB 的 POST 请求,你的响应可能会指定一个带有 public 指令的 Cache-Control 头来将该请求标记为可缓存。

🌐 Provided a POST request with a request body smaller than 1MB is sent, your response may specify a Cache-Control header with the public directive to mark the request as cacheable.

Expires 头文件

🌐 The Expires header

EAS Hosting 也支持使用较旧的 Expires header 进行缓存。

🌐 EAS Hosting also supports caching using the older Expires header.

由于这不会将响应标记为公开缓存,因此通常只用于未经过身份验证的 GET 响应。它可能会指定一个 HTTP 日期值,直到响应被缓存。在指定的时间戳之后,该响应被视为过期。

🌐 As this won't mark the response as publicly cacheable, it's typically only used for unauthenticated GET responses. It may specify an HTTP Date value until a response is cached. After the specified timestamp, the response is considered stale.

Vary 头文件

🌐 The Vary header

默认情况下:

🌐 By default:

  • 只有其 URL 的 GETHEAD 请求会被缓存
  • POST 请求仅根据其 URL 和请求主体进行缓存

然而,你可以使用 Vary 头来指定请求应使用请求头作为缓存键。例如,如果某个 API 路由返回 Vary: custom-header,那么只有在请求的 custom-header 头值与缓存请求的 custom-header 值匹配时,才会使用缓存的响应。

🌐 However, you can use the Vary header to specify that the request should be using request headers as a cache key. For example, if an API route responds with Vary: custom-header , then the cached response will only be used if the request's custom-header header value matches the cached request's custom-header value.

CORS 缓存

🌐 CORS caching

对于许多网页请求,浏览器会使用 OPTIONS 方法发起 CORS 请求,以确定某个路由的访问控制设置。

🌐 For many web requests, the browser will make CORS requests with the OPTIONS method to determine access control settings for a route.

这些请求可以使用特殊的 Access-Control-Max-Age 头进行缓存。例如,Access-Control-Max-Age: 3600 会将 OPTIONS 响应缓存 3600 秒,这适用于浏览器和 EAS 托管缓存。这可以防止浏览器发出过多请求,并防止你的 API 路径因 CORS 请求而被过度调用。

🌐 These requests are cacheable using the special Access-Control-Max-Age header. For example, Access-Control-Max-Age: 3600 will cache the OPTIONS response for 3600 seconds, which applies to both browsers and the EAS Hosting cache. This prevents excessive requests made by browsers and prevents your API route from being called excessively often for CORS requests.

资源缓存

🌐 Asset Caching

对于你的部署响应的任何资源,浏览器缓存将默认应用3600秒的缓存时间。为了提高性能,每个部署的资源在内部会被无限期缓存。由于部署是不可变的,这不会影响你。

🌐 For any assets your deployment responds with, a default cache time of 3600 seconds will be applied for browser caches. To improve performance, per-deployment assets are cached indefinitely internally. Since deployments are immutable, this doesn't affect you.

当你将新的部署分配给别名时,EAS 托管将忽略其缓存的资源。例如,当你将新的部署提升到生产环境时,缓存将被忽略,你的资源响应应立即切换到新的部署。

🌐 EAS Hosting will ignore its cached assets when you assign a new deployment to an alias. For example, when you promote a new deployment to production, the cache will be ignored and your asset responses should switch over to your new deployment instantly.

计费和指标

🌐 Billing and metrics

EAS 托管按请求计费(以每 100 万次请求为单位)。但是,缓存的请求仍然计入你的配额,即使这些请求被 EAS 托管缓存,你也将为这些请求付费。

🌐 EAS Hosting bills per request (in units of 1M requests). However, cached requests still count against your quota and you will be charged for requests, even if they are cached by EAS Hosting.

指标不会受到缓存的影响。被缓存的请求将像其他请求一样被记录,EAS 仪表板中的指标也会反映并显示缓存请求。

🌐 Metrics are not affected by caching. Cached requests will be logged like any other request, and the metrics in the EAS dashboard will also reflect and represent cached requests.