I have a web service with a method that takes quite a long time to complete. So I start the ajax client. It sends the request and it waits. Everything is fine when the request completes.
But when I use reload / refresh option in my browser (let's say Chrome) - all hell breaks loose. The pending request is shown in new page as still pending. The new pending request is made, but the old one still sits there. The new request lag or cease to respond.
A server fault? Not really, because all works fine when I restart the browser itself.
BTW, on latest Firefox my ajax app crashes when I reload the page during ajax fetch. I mean it hangs on first ajax request. Of course restarting the browser helps.
Here's configuration:
My service is a WCF service running on localhost. The service responds to GET
requests, however they must be authenticated with API key sent with a cookie. The service returns mostly JSON responses.
The communication uses CORS, no problems there.
I test my client using MiniWeb server. The application is pure ECMAScript, no framework or dependencies.
Here's my ajaxGet method:
/**
* Performs a GET request to the WCF, returns response data.
* @param {any} path Request path without domain and service path.
* @returns {object} Response data.
*/
async ajaxGet(path) {
let isFirstCookieSet = false;
if (this.serviceDomain === undefined) this.parseBaseUrl();
Cookie.set({ "api-key": this.apiKey }, { "domain": this.serviceDomain, "path": this.servicePath });
let response = null;
try {
response = await fetch(this.baseUrl + path, {
"method": "get",
"mode": "cors",
"credentials": "include"
});
} catch (error) {
console.info("Caught error during fetch operation before getting response body.");
throw new BackendError(404, "Service not available");
}
if (response.status !== 200) throw new BackendError(response.status, response.statusText);
let container = await response.json();
let data;
for (let k in container) if (container.hasOwnProperty(k)) {
data = container[k];
break;
}
Cookie.set({ "base-url": this.baseUrl, "api-key": this.apiKey }, { "expires": DateTime.now.addYears(1).value, "samedomain": true });
return data;
}
Well, it depends on my other code (obviously the App
class the method is a part of, DateTime
and BackendError
classes), but it's irrelevant here.
How to prevent this weird, undefined behavior?
Are there any special fetch
options? Should I set a specific request header? Should I set a specific response header in my web service? Any other magic?
UPDATE: I found I can abort the pending request manually:
How do I cancel an HTTP fetch() request?
But it would work if I could send a signal when browser reload is made, and AFAIK there's no way to execute any script when it happens. Or is it possible?