kkesley
kkesley

Reputation: 3396

JS Is it possible for fetch to not wait for response?

I have a logging API in which is executed before a link. The link will be redirecting the user to other place and I'm executing fetch before the user is redirected. So the script is like this now:

loggingAPI({
    timestamp: moment()
})
window.location = "http://.......com"

The logging api is just a normal fetch wrapper.

However, the server doesn't receive the API request right now. I think it's because of it doesn't even get the chance to send the request to the api.

So can I wait for the request to be sent but not waiting for the response?

Upvotes: 3

Views: 6285

Answers (3)

Tallboy
Tallboy

Reputation: 13407

An old question, but if you're using fetch you can use the keepalive flag.

The keepalive option can be used to allow the request to outlive the page. Fetch with the keepalive flag is a replacement for the Navigator.sendBeacon() API.

https://developer.mozilla.org/en-US/docs/Web/API/fetch#keepalive

Upvotes: 2

Jaromanda X
Jaromanda X

Reputation: 1

Using sendBeacon it's very simple

without seeing the code for you function loggingAPI the following is a best guess

Note: sendBeacon uses a POST request, so the server side may need to be modified to accept such a request - though, seeing as your loggingAPI is sending data, I imagine it is already using POST - so this may be a non-issue

somewhere in your code, set up an unload event for windows

window.addEventListener("unload", () => {
    sendBeacon("same url as loggingAPI", JSON.stringify({timestamp: moment()}));
}, false);

Then, when you

window.location = "http://.......com"

the loggingAPI function gets called for you

edit: sorry, I didn't flesh out the code fully, I missed a few steps!!

Upvotes: 6

Steven Spungin
Steven Spungin

Reputation: 29081

You can send the request in a service worker.

https://developers.google.com/web/fundamentals/primers/service-workers/

Here's some fetch specific information: https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent

You would register the service worker, and then send a message to it before redirecting.

The upside to the initial complexity is that once you start using service workers, they open up a whole new world of programming; You will end up using them for much more then queuing up messages to send.

Step 1 Register a service worker

index.html

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('service-worker.js').then(function(registration) {
      // Registration was successful
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }, function(err) {
      // registration failed :(
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}

Step 2 Create the service worker script

service-worker.js

self.addEventListener('install', function(e) {
    return Promise.resolve(null)
});

Step 3 Create a listener in server worker script

service-worker.js

self.addEventListener('message', function (event) {
  console.log('message', event.data)
  // call fetch here, catching and responding to what you stashed in the message      
});

Step 4 Send the message before you redirect

index.html

Just a demo to simulate your client.

 setTimeout(() => {
    navigator.serviceWorker.controller.postMessage({message: 'A LOG MESSAGE'});
  }, 2000)

After you put all pieces in place, MAKE SURE YOU CLOSE ALL TABS AND REOPEN, or have chrome dev tools set up to deal with refreshing the worker.

Upvotes: 3

Related Questions