123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /*
- Copyright 2018 Google LLC
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- import { WorkboxError } from './WorkboxError.js';
- import { logger } from './logger.js';
- import { assert } from './assert.js';
- import { getFriendlyURL } from '../_private/getFriendlyURL.js';
- import { pluginUtils } from '../utils/pluginUtils.js';
- import '../_version.js';
- /**
- * Wrapper around the fetch API.
- *
- * Will call requestWillFetch on available plugins.
- *
- * @param {Object} options
- * @param {Request|string} options.request
- * @param {Object} [options.fetchOptions]
- * @param {ExtendableEvent} [options.event]
- * @param {Array<Object>} [options.plugins=[]]
- * @return {Promise<Response>}
- *
- * @private
- * @memberof module:workbox-core
- */
- const wrappedFetch = async ({ request, fetchOptions, event, plugins = [], }) => {
- if (typeof request === 'string') {
- request = new Request(request);
- }
- // We *should* be able to call `await event.preloadResponse` even if it's
- // undefined, but for some reason, doing so leads to errors in our Node unit
- // tests. To work around that, explicitly check preloadResponse's value first.
- if (event instanceof FetchEvent && event.preloadResponse) {
- const possiblePreloadResponse = await event.preloadResponse;
- if (possiblePreloadResponse) {
- if (process.env.NODE_ENV !== 'production') {
- logger.log(`Using a preloaded navigation response for ` +
- `'${getFriendlyURL(request.url)}'`);
- }
- return possiblePreloadResponse;
- }
- }
- if (process.env.NODE_ENV !== 'production') {
- assert.isInstance(request, Request, {
- paramName: 'request',
- expectedClass: Request,
- moduleName: 'workbox-core',
- className: 'fetchWrapper',
- funcName: 'wrappedFetch',
- });
- }
- const failedFetchPlugins = pluginUtils.filter(plugins, "fetchDidFail" /* FETCH_DID_FAIL */);
- // If there is a fetchDidFail plugin, we need to save a clone of the
- // original request before it's either modified by a requestWillFetch
- // plugin or before the original request's body is consumed via fetch().
- const originalRequest = failedFetchPlugins.length > 0 ?
- request.clone() : null;
- try {
- for (const plugin of plugins) {
- if ("requestWillFetch" /* REQUEST_WILL_FETCH */ in plugin) {
- const pluginMethod = plugin["requestWillFetch" /* REQUEST_WILL_FETCH */];
- const requestClone = request.clone();
- request = await pluginMethod.call(plugin, {
- request: requestClone,
- event,
- });
- if (process.env.NODE_ENV !== 'production') {
- if (request) {
- assert.isInstance(request, Request, {
- moduleName: 'Plugin',
- funcName: "cachedResponseWillBeUsed" /* CACHED_RESPONSE_WILL_BE_USED */,
- isReturnValueProblem: true,
- });
- }
- }
- }
- }
- }
- catch (err) {
- throw new WorkboxError('plugin-error-request-will-fetch', {
- thrownError: err,
- });
- }
- // The request can be altered by plugins with `requestWillFetch` making
- // the original request (Most likely from a `fetch` event) to be different
- // to the Request we make. Pass both to `fetchDidFail` to aid debugging.
- const pluginFilteredRequest = request.clone();
- try {
- let fetchResponse;
- // See https://github.com/GoogleChrome/workbox/issues/1796
- if (request.mode === 'navigate') {
- fetchResponse = await fetch(request);
- }
- else {
- fetchResponse = await fetch(request, fetchOptions);
- }
- if (process.env.NODE_ENV !== 'production') {
- logger.debug(`Network request for ` +
- `'${getFriendlyURL(request.url)}' returned a response with ` +
- `status '${fetchResponse.status}'.`);
- }
- for (const plugin of plugins) {
- if ("fetchDidSucceed" /* FETCH_DID_SUCCEED */ in plugin) {
- fetchResponse = await plugin["fetchDidSucceed" /* FETCH_DID_SUCCEED */]
- .call(plugin, {
- event,
- request: pluginFilteredRequest,
- response: fetchResponse,
- });
- if (process.env.NODE_ENV !== 'production') {
- if (fetchResponse) {
- assert.isInstance(fetchResponse, Response, {
- moduleName: 'Plugin',
- funcName: "fetchDidSucceed" /* FETCH_DID_SUCCEED */,
- isReturnValueProblem: true,
- });
- }
- }
- }
- }
- return fetchResponse;
- }
- catch (error) {
- if (process.env.NODE_ENV !== 'production') {
- logger.error(`Network request for ` +
- `'${getFriendlyURL(request.url)}' threw an error.`, error);
- }
- for (const plugin of failedFetchPlugins) {
- await plugin["fetchDidFail" /* FETCH_DID_FAIL */].call(plugin, {
- error,
- event,
- originalRequest: originalRequest.clone(),
- request: pluginFilteredRequest.clone(),
- });
- }
- throw error;
- }
- };
- const fetchWrapper = {
- fetch: wrappedFetch,
- };
- export { fetchWrapper };
|