FetchEvent: respondWith() method
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018.
* Some parts of this feature may have varying levels of support.
Note: This feature is only available inService Workers.
TherespondWith() method ofFetchEvent prevents the browser's default fetch handling, andallows you to provide a promise for aResponse yourself.
In most cases you can provide any response that the receiver understands. For example,if an<img> initiates the request, the response body needs to beimage data. For security reasons, there are a few global rules:
- You can only return
Responseobjects oftype"opaque"if thefetchEvent.requestobject'smodeis"no-cors". This prevents theleaking of private data. - You can only return
Responseobjects oftype"opaqueredirect"if thefetchEvent.requestobject'smodeis"manual". - You cannot return
Responseobjects oftype"cors"if thefetchEvent.requestobject'smodeis"same-origin".
In this article
Syntax
respondWith(response)Parameters
Return value
None (undefined).
Exceptions
NetworkErrorDOMExceptionReturned if a network error is triggered on certain combinations of
FetchEvent.request.modeandResponse.typevalues, as hinted at in the "global rules"listed above.InvalidStateErrorDOMExceptionReturned if the event has not been dispatched or
respondWith()hasalready been invoked.
Description
>Specifying the final URL of a resource
From Firefox 59 onwards, when a service worker provides aResponse toFetchEvent.respondWith(), theResponse.url value will bepropagated to the intercepted network request as the final resolved URL. If theResponse.url value is the empty string, then theFetchEvent.request.url is used as the final URL.
In the past theFetchEvent.request.url was used as thefinal URL in all cases. The providedResponse.url was effectivelyignored.
This means, for example, if a service worker intercepts a stylesheet or worker script,then the providedResponse.url will be used to resolve any relative@import orimportScripts() subresource loads(Firefox bug 1222008).
For most types of network request this change has no impact because you can't observethe final URL. There are a few, though, where it does matter:
- If a
fetch()is intercepted,then you can observe the final URL on the result'sResponse.url. - If aworker script isintercepted, then the final URL is used to set
self.locationand used as the base URL for relative URLs in the worker script. - If a stylesheet is intercepted, then the final URL is used as the base URL forresolving relative
@importloads.
Note that navigation requests forWindows andiframes do NOT use the final URL. The way the HTMLspecification handles redirects for navigations ends up using the request URL for theresultingWindow.location. This means sites can still provide an"alternate" view of a web page when offline without changing the user-visible URL.
Examples
This fetch event tries to return a response from the cache API, falling back to thenetwork otherwise.
addEventListener("fetch", (event) => { // Prevent the default, and handle the request ourselves. event.respondWith( (async () => { // Try to get the response from a cache. const cachedResponse = await caches.match(event.request); // Return it if we found one. if (cachedResponse) return cachedResponse; // If we didn't find a match in the cache, use the network. return fetch(event.request); })(), );});Note:caches.match() is aconvenience method. Equivalent functionality is to callcache.match() on each cache (in the order returned bycaches.keys()) until aResponse is returned.
Specifications
| Specification |
|---|
| Service Workers Nightly> # fetch-event-respondwith> |