diff --git a/src/content/changelog/workers/2025-08-07-cache-no-cache.mdx b/src/content/changelog/workers/2025-08-07-cache-no-cache.mdx new file mode 100644 index 00000000000000..3a2a536dbb6530 --- /dev/null +++ b/src/content/changelog/workers/2025-08-07-cache-no-cache.mdx @@ -0,0 +1,37 @@ +--- +title: Requests made from Cloudflare Workers can now force a revalidation of their cache with the origin. +description: New runtime APIs allow you to control when subrequests revalidate cache, increasing compatibility with popular NPM packages +products: + - workers +date: 2025-08-07 +--- + +import { Render, PackageManagers, TypeScriptExample } from "~/components" + +By setting the value of the `cache` property to `no-cache`, you can force [Cloudflare's +cache](/workers/reference/how-the-cache-works/) to revalidate, its contents with the origin when +making subrequests from [Cloudflare Workers](/workers). + + +```ts +export default { + async fetch(req, env, ctx): Promise { + const request = new Request("https://cloudflare.com", { cache: 'no-cache'}); + const response = await fetch(request); + return response; + } +} satisfies ExportedHandler +``` + + +When you set the value to `no-cache` on a subrequest made from a Worker, the Cloudflare Workers +runtime will force the cache to revalidate its data with the origin + +This increases compatibility with NPM packages and JavaScript frameworks that rely on setting the +[`cache`](/workers/runtime-apis/request/#options) property, which is a cross-platform standard part +of the [`Request`](/workers/runtime-apis/request/) interface. Previously, if you set the `cache` +property on `Request` to `'no-cache'`, the Workers runtime threw an exception. + +* Learn [how the Cache works with Cloudflare Workers](/workers/reference/how-the-cache-works/) +* Enable [Node.js compatibility](/workers/runtime-apis/nodejs/) for your Cloudflare Worker +* Explore [Runtime APIs](/workers/runtime-apis/) and [Bindings](/workers/runtime-apis/bindings/) available in Cloudflare Workers \ No newline at end of file diff --git a/src/content/compatibility-flags/cache-no-cache.md b/src/content/compatibility-flags/cache-no-cache.md new file mode 100644 index 00000000000000..e8bd8367c1d830 --- /dev/null +++ b/src/content/compatibility-flags/cache-no-cache.md @@ -0,0 +1,36 @@ +--- +name: "Enable `cache: no-cache` HTTP standard API" +sort_date: "2025-08-07" +enable_date: "2025-08-07" +enable_flag: "cache_no_cache_enabled" +disable_flag: "cache_no_cache_disabled" +--- + +When you enable the `cache_no_cache_enabled` compatibility flag, you can specify the `no-cache` +value for the `cache` property of the Request interface. When this compatibility flag is not +enabled, or `cache_option_disabled` is set, the Workers runtime will throw a `TypeError` saying +`Unsupported cache mode: no-cache`. + +When this flag is enabled you can instruct Cloudflare to force its cache to revalidate the +response from a subrequest you make from your Worker using the [`fetch()` +API](/workers/runtime-apis/fetch/): + +When `no-cache` is specified: + +- All requests have the headers `Pragma: no-cache` and `Cache-Control: no-cache` are set on them. + +- Subrequests to origins not hosted by Cloudflare force Cloudflare's cache to revalidate with the +origin. + +Examples using `cache: 'no-cache'`: + +```js +const response = await fetch("https://example.com", { cache: "no-cache" }); +``` + +The cache value can also be set on a `Request` object. + +```js +const request = new Request("https://example.com", { cache: "no-cache" }); +const response = await fetch(request); +``` \ No newline at end of file diff --git a/src/content/docs/workers/examples/cache-using-fetch.mdx b/src/content/docs/workers/examples/cache-using-fetch.mdx index 8dbf4a798f29ed..b287e0670b6f44 100644 --- a/src/content/docs/workers/examples/cache-using-fetch.mdx +++ b/src/content/docs/workers/examples/cache-using-fetch.mdx @@ -554,9 +554,12 @@ async function handleRequest(request) { ## Using the HTTP Cache API The `cache` mode can be set in `fetch` options. -Currently Workers only support the `no-store` mode for controlling the cache. +Currently Workers only support the `no-store` and `no-cache` mode for controlling the cache. When `no-store` is supplied the cache is bypassed on the way to the origin and the request is not cacheable. +When `no-cache` is supplied the cache is forced to revalidate the currently cached response with the +origin. ```js fetch(request, { cache: 'no-store'}); +fetch(request, { cache: 'no-cache'}); ``` \ No newline at end of file diff --git a/src/content/docs/workers/runtime-apis/fetch.mdx b/src/content/docs/workers/runtime-apis/fetch.mdx index b8dd8d5a336a07..b3188714d41017 100644 --- a/src/content/docs/workers/runtime-apis/fetch.mdx +++ b/src/content/docs/workers/runtime-apis/fetch.mdx @@ -80,11 +80,13 @@ async def on_scheduled(controller, env, ctx): - [`resource`](https://developer.mozilla.org/en-US/docs/Web/API/fetch#resource) Request | string | URL - `options` options - - `cache` `undefined | 'no-store'` optional - - Standard HTTP `cache` header. Only `cache: 'no-store'` is supported. + - `cache` `undefined | 'no-store' | 'no-cache'` optional + - Standard HTTP `cache` header. Only `cache: 'no-store'` and `cache: 'no-cache'` are supported. Any other `cache` header will result in a `TypeError` with the message `Unsupported cache mode: `. _ For all requests this forwards the `Pragma: no-cache` and `Cache-Control: no-cache` headers to the origin. - _ For requests to origins not hosted by Cloudflare, `no-store` bypasses the use of Cloudflare's caches. + _ For `no-store`, requests to origins not hosted by Cloudflare bypass the use of Cloudflare's caches. + _ For `no-cache`, requests to origins not hosted by Cloudflare are forced to revalidate with + the origin before resonding. - An object that defines the content and behavior of the request. --- @@ -132,4 +134,4 @@ export default { - [Example: Fetch HTML](/workers/examples/fetch-html/) - [Example: Fetch JSON](/workers/examples/fetch-json/) - [Example: cache using Fetch](/workers/examples/cache-using-fetch/) -- Write your Worker code in [ES modules syntax](/workers/reference/migrate-to-module-workers/) for an optimized experience. +- Write your Worker code in [ES modules syntax](/workers/reference/migrate-to-module-workers/) for an optimized experience. \ No newline at end of file diff --git a/src/content/docs/workers/runtime-apis/request.mdx b/src/content/docs/workers/runtime-apis/request.mdx index 0571113efb32b4..dabd03871224b7 100644 --- a/src/content/docs/workers/runtime-apis/request.mdx +++ b/src/content/docs/workers/runtime-apis/request.mdx @@ -62,9 +62,9 @@ let request = new Request(input, options) An object containing properties that you want to apply to the request. -* `cache` `undefined | 'no-store'` optional +* `cache` `undefined | 'no-store' | 'no-cache'` optional - * Standard HTTP `cache` header. Only `cache: 'no-store'` is supported. + * Standard HTTP `cache` header. Only `cache: 'no-store'` and `cache: 'no-cache'` are supported. Any other cache header will result in a `TypeError` with the message `Unsupported cache mode: `. * `cf` RequestInitCfProperties optional @@ -432,4 +432,4 @@ Using any other type of `ReadableStream` as the body of a request will result in * [Examples: Modify request property](/workers/examples/modify-request-property/) * [Examples: Accessing the `cf` object](/workers/examples/accessing-the-cloudflare-object/) * [Reference: `Response`](/workers/runtime-apis/response/) -* Write your Worker code in [ES modules syntax](/workers/reference/migrate-to-module-workers/) for an optimized experience. +* Write your Worker code in [ES modules syntax](/workers/reference/migrate-to-module-workers/) for an optimized experience. \ No newline at end of file