3

I wanted to convert a web form to work offline. Originally, I would store the form information in a sql database on the web server after the user completed each step. One of the steps included uploading images, for which I implemented a progress bar.

After adding a service worker, I noticed that the progress bar no longer worked (the bar would be displayed, but would never get updated to show how much of the file had been uploaded). I tested in multiple browsers to make sure this wasn't browser dependent and had the same results in all of them (chrome, firefox, edge, safari, mobile versions as well).

Here is the first part of my ajax request.

$.ajax({
    type: "POST",
    url: url,
    datatype: "json",
    data: JSON.stringify(data),
    xhr: function () {
        var xhr = new window.XMLHttpRequest();
        xhr.upload.addEventListener("progress", function (evt) {
            if (evt.lengthComputable) {
                var percentComplete = getCurrentProgress(evt.loaded, evt.total);
                $("#progressBarContainer .progress > .progress-bar").css({ "width": percentComplete + "%" });
                $("#progressBarContainer .progress > .progress-bar .percent-complete").text(percentComplete + "%");
            }
        }, false);

        return xhr;
    }
})

Here is the code in my service worker file to handle fetch events.

self.addEventListener("fetch", event => {
    event.respondWith(
        caches.open(staticCacheName)
            .then(cache => {
                return cache.match(event.request)
                    .then(response => {
                        if (response) {
                            return response;
                        }
                        else {
                            return fetch(event.request);
                        }
                    });
            })
    );
});

I was able to find a solution, but couldn't find this question on stackoverflow, so I'm posting and answering my own question. If anyone has any comments for improvement or a better solution, please let me know.

joeshmoe301
  • 1,193
  • 2
  • 11
  • 25

2 Answers2

5

I found the answer here. What I needed to do is have the service worker ignore post requests. I updated my service worker code to this:

self.addEventListener("fetch", event => {
    //This is the code that ignores post requests
    if (event.request.method === "POST") {
        return;
    }

    event.respondWith(
        caches.open(staticCacheName)
            .then(cache => {
                return cache.match(event.request)
                    .then(response => {
                        if (response) {
                            return response;  //The URL is cached
                        }
                        else {
                            return fetch(event.request);  //Go to the network.
                        }
                    });
            })
    );
});
joeshmoe301
  • 1,193
  • 2
  • 11
  • 25
0

If you are looking for a progressbar which can tell you how much contents have been loaded into the cache storage using service worker, it's nearly impossible as SW don't have access to DOM. But you can counter this issue from the other side. Please have a look into this https://stackoverflow.com/a/54222155/9900456 as well as there are other answers to the your questions too! Cheers :)

zaffar
  • 679
  • 6
  • 13