Door
Onbekende gebruiker
op 21-06-2021 22:35
gewijzigd op 21-06-2021 22:36
6.575 views
Ik heb een simpele javascript-functie die het altijd deed, totdat de klant eindelijk overstapte naar Edge.
Het gekke is dat de functie wel gewoon werkt met Internet Explorer en Firefox.
window.addEventListener('unload', function() {
let oXhr = new XMLHttpRequest();
let sUrl = document.getElementById('xhrAfmelden').getAttribute('href');
oXhr.open('POST', sUrl, false); // sync, anders venter te vroeg gesloten
oXhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
formData.append('_CSRF_', sToken);
oXhr.send();
});
De code moet er voor zorgen dat wanneer een venster gesloten wordt, de gebruiker automatisch wordt uitgelogd.
Het is nodig omdat bijna geen enkele gebruiker zichzelf uitlogt.
Maar sinds kort verschijnt hierdoor in mijn JS-foutlog vanuit Edge deze melding:
Het lijkt er op dat Edge (en evt. andere webkit browsers) de XMLHttpRequest niet afmaakt. Als ik de derde parameter van open() op true zet, werkt het soms wel met Edge, maar meestal niet. Wel krijg ik altijd de vraag van Edge 'Site opnieuw laden?.
Als ik het probeer met onbeforeunload gebeurt er helemaal niets, dus ik heb ff geen flauw idee hoe nu verder.
Weet iemand een oplossing?
?Onbekende gebruiker
08-08-2021 13:03
ff proberen.. dus ik klik op het slotje, dan onder machtigingen over deze site - Cookies. Dan onder de tab Toegestaan moet ik de site (opnieuw) kiezen door het op te klappen, dan cookies openklappen, dan een cookie selecteren, dan naar beneden scrollen in het hoofddeel (het binnenvenster van cookies kan ook gescrolld, dan moet ik op verwijderen klikken totdat alle cookies verwijderd zijn, dan op gereed klikken en de pagina herladen.
Ofwel.. dat gaat hem niet worden, geen normaal mens (lees: niet-IT-er) gaat dit onthouden. Met als gevolg dat ze de webapplicatie terecht de schuld gaan geven.
Als de applicatie wordt afgesloten is er een event dat een XHR-request doet, maar de response niet afwacht met dank aan Google (Chrome). Ik krijg dan deze JavaScript error:
"Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://mijnsite.nl/': Synchronous XHR in page dismissal. See https://www.chromestatus.com/feature/4664843055398912 for more details."
Maar hoe moet het dan?
[size=xsmall]Toevoeging op 08/08/2021 13:13:56:[/size]
Nog even gezocht en kwam uit bij SO, het schijnt te kunnen met sessionStorage.
Dit uitzoeken wordt de volgende stap...
Leuke is dat je in $_COOKIE een hele array hebt met al je cookies. Die kan je gewoon doorlopen met foreach, en dan verwijderen door ze met setcookie() om te zetten naar een cookie met negatieve datum.
Zo heb ik pas geleden nog een cookie-overzicht voor mijn site gemaakt.
Nog even gezocht en kwam uit bij SO, het schijnt te kunnen met sessionStorage.
sessionStorage en LocalStorage is niet moeilijk hoor. Wel enkel via javascript
tip: start je js met let stor = window["localStorage"]; of let stor = window["sessionStorage"]; dan kan je eenvoudig tussen de 2 wissellen.
Jan
?Onbekende gebruiker
09-08-2021 10:24
gewijzigd op 09-08-2021 10:24
Ik ben er nog niet helemaal uit.
Ik heb nu (voor de veiligheid) strikte HTTP-cookies waar JS niet bij kan. Wel heeft elke tab een JS variabele met de tab id, die wordt meegestuurd in het XHR-verzoek om te weten om welke cookie het gaat (de tab id is onderdeel van de cookienaam). Maar bij het sluiten van de tab kan je in JS niet de cookie unsetten.
Tegenwoordig kan je niet meer wachten op een HTTP response tijdens een document.unload event, waardoor de browser niet gecommuniceerd krijgt dat de cookie verwijderd moet worden. Het blijft actief in de browser totdat je de browser sluit. En voor elke nieuwe tab stuurt-ie oude cookies mee van tabs die er misschien al lang niet meer zijn.
Een stukje GC kan ingebouwd door bij het laden van de pagina (het is een SPA) te kijken welke cookies er worden meegestuurd naar PHP. Als er verlopen cookies tussenzitten kan PHP die inderdaaad alsnog laten verlopen via setcoookie(). Het maakt de kans kleiner dat de request buffer van de webserver vol zal lopen.
Maar dit is geen ideale oplossingsrichting. Misschien kan ik toch 1 cookienaam gebruiken, en de tab id uit de sessionStorage (of waar het ook staat) verwerken in de XHR-verzoeken (de hele SPA werkt met alleen maar XHR), zodat de webapplicatie ook al weet om welke sessie het gaat. Dan zou ik voor de hele SPA nog maar 1 'gebundelde' cookie nodig hebben.
Ik ga eens kijken of die oplossing te maken valt.
Kun je wellicht in plaats van bij het sluiten van een tabblad, tijdens het openen van een tabblad controleren op bestaande cookies? En op dat moment de inactieve cookies verwijderen?
?Onbekende gebruiker
09-08-2021 11:31
gewijzigd op 09-08-2021 11:40
Ja dat was wat ik bedoelde met de voorlaatste alinea van mijn vorige post.
Maar ik heb er nog even over nagedacht, en eigenlijk kan wat ik wil niet langer.
Het probleem is dat cookies niet verlopen dankzij de max-age=0 (anders werkt het niet eens goed), en dat de server de cookies op de browser niet meer goed kan beheren vanwege het missende synchrone unload event. De browser stuurt elke keer alle mee, en met de JS variabele kan de server onderscheid maken.
Maar dan blijven van gesloten tabs alle cookies in de browser totdat de browser gesloten wordt.
Dat werkt dus niet goed.
Ik ben zo snugger geweest om nu pas een keer te gaan kijken hoe de Fritz!Box het dan wel voor elkaar krijgt, en het antwoord is een grote teleurstelling: de Fritz!Box gebruikt daarvoor geen cookies, maar gooit de SID gewoon in de URL, zelfs over HTTP(!).
De uitkomst is dat ik een SID per browser tab wel kan vergeten, wil je het goed geregeld hebben. De business kan er gelukkig omheen, ze hebben tegenwoordig ipv. IE11 nu Edge én Firefox, dus ik kan het net zo goed weer allemaal terugveranderen.