ServiceWorker - 在脱机时缓存所有失败的帖子请求,并在联机时重新提交

时间:2016-08-17 00:19:00

标签: javascript service-worker

我的服务人员此刻成功实现了以下目标:

  • 它会缓存在线时访问的所有页面
  • 它只在离线时返回缓存页面

我的应用程序能够让用户输入通过ajax自动提交的签名。我试图在我的服务工作人员离线时捕获此帖子请求,并在他们上线后立即重新提交相同的请求。

以下是我的serviceworker文件示例。

self.addEventListener('fetch', function(event) {
    // Intercept all fetch requests from the parent page
    event.respondWith(
        caches.match(event.request)
        .then(function(response) {
            // Immediately respond if request exists in the cache and user is offline
            if (response && !navigator.onLine) {
                return response;
            }


            // IMPORTANT: Clone the request. A request is a stream and
            // can only be consumed once. Since we are consuming this
            // once by cache and once by the browser for fetch, we need
            // to clone the response
            var fetchRequest = event.request.clone();

            // Make the external resource request
            return fetch(fetchRequest).then(
                function(response) {
                // If we do not have a valid response, immediately return the error response
                // so that we do not put the bad response into cache
                if (!response || response.status !== 200 || response.type !== 'basic') {
                    return response;
                }

                // IMPORTANT: Clone the response. A response is a stream
                // and because we want the browser to consume the response
                // as well as the cache consuming the response, we need
                // to clone it so we have 2 stream.
                var responseToCache = response.clone();

                // Place the request response within the cache
                caches.open(CACHE_NAME)
                .then(function(cache) {
                    if(event.request.method !== "POST")
                    {
                        cache.put(event.request, responseToCache);
                    }
                });

                return response;
            }
            );
        })
    );
});

我想弄清楚合并这个的最佳方法?有人能够解决一些问题吗?

1 个答案:

答案 0 :(得分:3)

我已通过以下评论中的以下代码实现了我想要的结果。

// Cache signature post request
    //This retrieves all the information about the POST request including the formdata body, where the URL contains updateSignature.
// Resubmit offline signature requests
    //This resubmits all cached POST results and then empties the array.

self.addEventListener('fetch', function(event) {
    // Intercept all fetch requests from the parent page
    event.respondWith(
        caches.match(event.request)
        .then(function(response) {
            // Cache signature post request
            if (event.request.url.includes('updateSignature') && !navigator.onLine) {
                var request = event.request;
                var headers = {};
                for (var entry of request.headers.entries()) {
                    headers[entry[0]] = entry[1];
                }
                var serialized = {
                    url: request.url,
                    headers: headers,
                    method: request.method,
                    mode: request.mode,
                    credentials: request.credentials,
                    cache: request.cache,
                    redirect: request.redirect,
                    referrer: request.referrer
                };
                request.clone().text().then(function(body) {
                    serialized.body = body;
                    callsToCache.push(serialized);
                    console.log(callsToCache);
                });     
            }
            // Immediately respond if request exists in the cache and user is offline
            if (response && !navigator.onLine) {
                return response;
            }
            // Resubmit offline signature requests
            if(navigator.onLine && callsToCache.length > 0) {
                callsToCache.forEach(function(signatureRequest) {
                    fetch(signatureRequest.url, {
                        method: signatureRequest.method,
                        body: signatureRequest.body
                    })
                });
                callsToCache = [];
            }


            // IMPORTANT: Clone the request. A request is a stream and
            // can only be consumed once. Since we are consuming this
            // once by cache and once by the browser for fetch, we need
            // to clone the response
            var fetchRequest = event.request.clone();

            // Make the external resource request
            return fetch(fetchRequest).then(
                function(response) {
                // If we do not have a valid response, immediately return the error response
                // so that we do not put the bad response into cache
                if (!response || response.status !== 200 || response.type !== 'basic') {
                    return response;
                }

                // IMPORTANT: Clone the response. A response is a stream
                // and because we want the browser to consume the response
                // as well as the cache consuming the response, we need
                // to clone it so we have 2 stream.
                var responseToCache = response.clone();

                // Place the request response within the cache
                caches.open(CACHE_NAME)
                .then(function(cache) {
                    if(event.request.method !== "POST")
                    {
                        cache.put(event.request, responseToCache);
                    }
                });

                return response;
            }
            );
        })
    );
});