force all page visits to refresh/clear cache after login/logout - javascript

My site is constructed entirely of dynamic data, some of which changes based on user authentication. When a user "logs in" to the site, I show their new status with their user name in the page navigation bar. However when they visit a page they visited recently before authenticating (back button, etc), that page's version of the navigation bar will not be refreshed. What are some methods to force a refreshed page to the browser? The inverse is also true: if a user logs out, recent pages will still show authenticated from the cached version.
What technique can I use to always force a browser-side refresh/clear cache on any page on the website?
Thanks.
Nb: server side I am using eXist-db 4.7's login:set-user() to authenticate a user (i.e. "log them in") through the controller.

The best source I found for your problem was the following blog article that explains caching in a way that even I could understand: https://jakearchibald.com/2016/caching-best-practices/
TLDR:
Don't try to fix this on the client side, let the server take care of this.
Add the following response header on the server side:
Cache-Control: no-cache

#MauriceNino had already covered almost all the technical methods, though there is one more that exist in certain scenarios.
Not the best solution but if all your pages are created with certain dynamic url with parameters, you can just add a new parameter "v" or "version" = random login session key.
To make this happen, all and any URL's (that you don't want to cache) should be concatenated with above parameters. Create a centralized method to call ajax or pages and add this version parameter. Every time you login a new unique parameter will be created. Browser will always hit for a new request if the parameter is changed.
Though the down side to this is that your URL's won't be pretty. All your URL's would have to go through a filter (which i guess you would already have)

I suggest you to check out this thread, for some more specific information, but to sum it up:
You need to check if the loginState changed
You need to refresh the page if it did
Solution 1)
Step 1
You need to initialize a global variable like this:
let loginStateChanged = false;
And when the user logs in or out, you do:
loginStateChanged = true;
Step 2
You need to listen for "browser back-button events" and refresh the window if the login state has changed.
You can use the pageshow event like so:
window.addEventListener('pageshow', (event) => {
var isBackNavigation = event.persisted ||
(typeof window.performance != 'undefined' && window.performance.navigation.type === 2);
// If the navigation type is a back navigation, and the login
// State has changed, refresh the window
if (isBackNavigation && loginStateChanged) {
window.location.reload(); // reload the page
}
});
Or with jQuery;
$(window).on('popstate', () => {
// If the login State has changed, refresh the window
if (loginStateChanged) {
window.location.reload(); // reload the page
}
});
Becuase the window refreshed, the loginStateChanged will be reset to its default value false.
Solution 2)
Or if you need to implement the solution for multiple tabs:
Step 1
Use localStorage and a global variable instead:
let isLoggedIn = JSON.parse(localStorage.getItem('isLoggedIn')); // Get the initial value
isLoggedIn = isLoggedIn != 'undefined' ? isLoggedIn : false; // If initial value is undefined, set it to false
And when the user logs in or out, you do:
isLoggedIn = /* login: true, logout: false */; // update global variable
localStorage.setItem('isLoggedIn', JSON.stringify(isLoggedIn)); // update localStorage variable
Step 2
window.addEventListener('pageshow', (event) => {
var isBackNavigation = event.persisted ||
(typeof window.performance != 'undefined' && window.performance.navigation.type === 2);
// If the navigation type is a back navigation, and the login
// State has changed, refresh the window
// Here you check, if the localStorage variable is different, than the global variable
if (isBackNavigation && JSON.parse(localStorage.getItem('isLoggedIn')) != isLoggedIn) {
window.location.reload(); // reload the page
}
});
Solution 3)
If you want to refresh on any back or forward click, just use this code:
window.addEventListener('pageshow', (event) => {
var isNavigation = event.persisted ||
(typeof window.performance != 'undefined' && window.performance.navigation.type === 2);
if (isNavigation) {
window.location.reload();
}
});
Solution 3 Test-files:
test1.html and test2.html (they are exactly the same):
<html>
<head>
<title>test</title>
<script>
window.addEventListener("pageshow", function ( event ) {
var isNavigation = event.persisted ||
(typeof window.performance != 'undefined' && window.performance.navigation.type === 2);
console.log("Is navigated through button? ", isBackNavigation);
if (isNavigation) {
alert("reload!");
window.location.reload();
}
});
</script>
</head>
Test1
Test2
</html>
It will refresh the whole page on every navigation action. And on the opening of a new tab it will reload it anyways.

Related

How to determine whether the user closes browser tab or refreshes the page

I am building a two person game app using vue.js. The app uses vuex for state management and Firestore as the backend server.
If the user leaves the app by either closing the browser tab or navigating away, the games Firestore files need to be deleted. However, if the user refreshes the page, the Firestore files need to remain so that the reload process can repopulate the game.
So I need to determine if the user has refreshed the page as opposed to closing the browser or navigating away.
As shown below, in vue's created lifecycle I setup a "beforeunload" event Listener and also start my Firestore listeners
created() {
// This window event listener fires when the user
// navigates away from or closes the browser window
window.addEventListener("beforeunload", (event) => {
const isByRefresh = getUnloadInitiator();
if (!isByRefresh) {
this.stopFirestoreListeners("beforeunload");
}
// Cancel the event. This allows the user to cancel via popup. (for debug purposes)
event.preventDefault();
event.returnValue = "";
// the absence of a returnValue property on the event
// guarantees the browser unload happens
// delete event["returnValue"];
});
this.startFirestoreListeners("created");
},
The getUnloadInitiator function is shown below. This is where I need help. Right now all this function does is console.log various performance values.
function getUnloadInitiator() {
// check for feature support before continuing
if (performance.mark === undefined) {
console.log("performance.mark NOT supported");
return false;
}
console.log("===============================");
// Yes I know that performance.navigation is depreciated.
const nav = performance.navigation;
console.log("nav=", nav);
console.log("===============================");
// Use getEntriesByType() to just get the "navigation" events
var perfEntries = performance.getEntriesByType("navigation");
for (var i = 0; i < perfEntries.length; i++) {
var p = perfEntries[i];
console.log("= Navigation entry[" + i + "]=", p);
// other properties
console.log("type = " + p.type);
}
console.log("===============================");
performance.mark("beginLoop");
const entries = performance.getEntries({
name: "beginLoop",
entryType: "mark",
});
const firstEntry = entries[0];
console.log("firstEntry.type=", firstEntry.type);
console.log("===============================");
//TODO: Determine how unload was initiated
return true;
}
Below is the output from my console.logs. They are the same for refreshing the page, closing the browser tab, or navigating away. All show "reload" as the navigation type.
===============================
nav= PerformanceNavigation {type: 1, redirectCount: 0}
===============================
= Navigation entry[0]= PerformanceNavigationTiming {unloadEventStart: 25.399999976158142, unloadEventEnd: 25.69999998807907, domInteractive: 633, domContentLoadedEventStart: 633, domContentLoadedEventEnd: 633, …}
type = reload
===============================
firstEntry.type= reload
===============================
Any help on how to differentiate between refreshing the page, closing the browser tab, or navigating away would be appreciated. There must be away, because the native cancel browser popup I'm using for debug purposes differentiates between fresh and browser tab close.
Thanks
You can use a source of authority as persistence, be it firestore, local storage, or cookies. you are able to get the browser's tab ID with tab.id and compare it to an existing one should one exist.
browser.pageAction.show(tab.id);
Source: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_the_Tabs_API

Check if page is loaded from bfcache, HTTP cache, or newly retrieved

the code below checks whether a url is loaded and then logs to the console. I would like to know if there is simple, clean method to check if a page is loaded from bfcache or http cache? Firefox documentation states that the load event should not be triggered if I go from URL A to B and then hit the back button to URL A, but this is not my experience, both load and PageShow is logged regardless, does anyone know why?
var tabs = require("sdk/tabs");
function onOpen(tab) {
tab.on("pageshow", logPageShow);
tab.on("load", logLoading);
}
function logPageShow(tab) {
console.log(tab.url + " -- loaded (maybe from bfcache?) ");
}
function logLoading(tab) {
console.log(tab.url + " -- loaded (not from bfcache) ");
}
tabs.on('open', onOpen);
I am not sure whether there is any purposeful API for that but a workaround that came to mind is to check value of the performance.timing.responseEnd - performance.timing.requestStart. If it is <= 5 then most likely it is HTTP or back-forward cache. Otherwise, it is a download from the web.
A way to recognize a return to the page through a back button instead of opening up a clean URL is to use history API. For example:
// on page load
var hasCameBack = window.history && window.history.state && window.history.state.customFlag;
if (!hasComeBack) {
// most likely, user has come by following a hyperlink or entering
// a URL into browser's address bar.
// we flag the page's state so that a back/forward navigation
// would reveal that on a comeback-kind of visist.
if (window.history) {
window.history.replaceState({ customFlag: true }, null, null);
}
}
else {
// handle the comeback visit situation
}
See also Manipulating the browser history article at MDN.

How to fire the ajax request with same post parameter when browser back button is pressed?

I need to fire the ajax request with same post parameters when browser back button is pressed. any way to remember the query or either the page post parameter that was passed with the ajax fire before back button is pressed.
I search through web an found those methods
Use localsotrage (when the page unloads) or document.location.hash
Or use Cookie (Not prefered)
window.onbeforeunload = function (e) {
if (('localStorage' in window) && window['localStorage'] !== null) {
localStorage.setItem('myVar', $_POST['start']);
}
}
if( isNaN(start)) {
if (('localStorage' in window) && window['localStorage'] !== null) {
if ('myVar' in localStorage || window.location.hash) {
start = localStorage.getItem('myVar');
} // Was Missing
}
}
you can try uriAnchor plugin
It provides the capability to make the URI fragment your application state API. Bookmarks, browser history, the back button, and the forward button can all be made to act as the user expects while enabling you to update only the part of the page that has changed.

Ajax with history.pushState and popstate - what do I do when popstate state property is null?

I'm trying out the HTML5 history API with ajax loading of content.
I've got a bunch of test pages connected by relative links. I have this JS, which handles clicks on those links. When a link is clicked the handler grabs its href attribute and passes it to ajaxLoadPage(), which loads content from the requested page into the content area of the current page. (My PHP pages are set up to return a full HTML page if you request them normally, but only a chunk of content if ?fragment=true is appended to the URL of the request.)
Then my click handler calls history.pushState() to display the URL in the address bar and add it to the browser history.
$(document).ready(function(){
var content = $('#content');
var ajaxLoadPage = function (url) {
console.log('Loading ' + url + ' fragment');
content.load(url + '?fragment=true');
}
// Handle click event of all links with href not starting with http, https or #
$('a').not('[href^=http], [href^=https], [href^=#]').on('click', function(e){
e.preventDefault();
var href = $(this).attr('href');
ajaxLoadPage(href);
history.pushState({page:href}, null, href);
});
// This mostly works - only problem is when popstate happens and state is null
// e.g. when we try to go back to the initial page we loaded normally
$(window).bind('popstate', function(event){
console.log('Popstate');
var state = event.originalEvent.state;
console.log(state);
if (state !== null) {
if (state.page !== undefined) {
ajaxLoadPage(state.page);
}
}
});
});
When you add URLs to the history with pushState you also need to include an event handler for the popstate event to deal with clicks on the back or forward buttons. (If you don't do this, clicking back shows the URL you pushed to history in the address bar, but the page isn't updated.) So my popstate handler grabs the URL saved in the state property of each entry I created, and passes it to ajaxLoadPage to load the appropriate content.
This works OK for pages my click handler added to the history. But what happens with pages the browser added to history when I requested them "normally"? Say I land on my first page normally and then navigate through my site with clicks that do that ajax loading - if I then try to go back through the history to that first page, the last click shows the URL for the first page, but doesn't load the page in the browser. Why is that?
I can sort of see this has something to do with the state property of that last popstate event. The state property is null for that event, because it's only entries added to the history by pushState() or replaceState() that can give it a value. But my first loading of the page was a "normal" request - how come the browser doesn't just step back and load the initial URL normally?
This is an older question but there is a much simpler answer using native javascript for this issue.
For the initial state you should not be using history.pushState but rather history.replaceState.
All arguments are the same for both methods with the only difference is that pushState creates a NEW history record and thus is the source of your problem. replaceState only replaces the state of that history record and will behave as expected, that is go back to the initial starting page.
I ran into the same issue as the original question. This line
var initialPop = !popped && location.href == initialURL;
should be changed to
var initialPop = !popped;
This is sufficient to catch the initial pop. Then you do not need to add the original page to the pushState. i.e. remove the following:
var home = 'index.html';
history.pushState({page:home}, null, home);
The final code based on AJAX tabs (and using Mootools):
if ( this.supports_history_api() ) {
var popped = ('state' in window.history && window.history.state !== null)
, changeTabBack = false;
window.addEvent('myShowTabEvent', function ( url ) {
if ( url && !changingTabBack )
setLocation(url);
else
changingTabBack = false;
//Make sure you do not add to the pushState after clicking the back button
});
window.addEventListener("popstate", function(e) {
var initialPop = !popped;
popped = true;
if ( initialPop )
return;
var tabLink = $$('a[href="' + location.pathname + '"][data-toggle*=tab]')[0];
if ( tabLink ) {
changingTabBack = true;
tabLink.tab('show');
}
});
}
I still don't understand why the back button behaves like this - I'd have thought the browser would be happy to step back to an entry that was created by a normal request. Maybe when you insert other entries with pushState the history stops behaving in the normal way. But I found a way to make my code work better. You can't always depend on the state property containing the URL you want to step back to. But stepping back through history changes the URL in the address bar as you would expect, so it may be more reliable to load your content based on window.location. Following this great example I've changed my popstate handler so it loads content based on the URL in the address bar instead of looking for a URL in the state property.
One thing you have to watch out for is that some browsers (like Chrome) fire a popstate event when you initially hit a page. When this happens you're liable to reload your initial page's content unnecessarily. So I've added some bits of code from the excellent pjax to ignore that initial pop.
$(document).ready(function(){
// Used to detect initial (useless) popstate.
// If history.state exists, pushState() has created the current entry so we can
// assume browser isn't going to fire initial popstate
var popped = ('state' in window.history && window.history.state !== null), initialURL = location.href;
var content = $('#content');
var ajaxLoadPage = function (url) {
console.log('Loading ' + url + ' fragment');
content.load(url + '?fragment=true');
}
// Handle click event of all links with href not starting with http, https or #
$('a').not('[href^=http], [href^=https], [href^=#]').on('click', function(e){
e.preventDefault();
var href = $(this).attr('href');
ajaxLoadPage(href);
history.pushState({page:href}, null, href);
});
$(window).bind('popstate', function(event){
// Ignore inital popstate that some browsers fire on page load
var initialPop = !popped && location.href == initialURL;
popped = true;
if (initialPop) return;
console.log('Popstate');
// By the time popstate has fired, location.pathname has been changed
ajaxLoadPage(location.pathname);
});
});
One improvement you could make to this JS is only to attach the click event handler if the browser supports the history API.
I actually found myself with a similar need today and found the code you provided to be very useful. I came to the same problem you did, and I believe all that you're missing is pushing your index file or home page to the history in the same manner that you are all subsequent pages.
Here is an example of what I did to resolve this (not sure if it's the RIGHT answer, but it's simple and it works!):
var home = 'index.html';
history.pushState({page:home}, null, home);
Hope this helps!
I realize this is an old question, but when trying to manage state easily like this, it might be better to take the following approach:
$(window).on('popstate',function(e){
var state = e.originalEvent.state;
if(state != null){
if(state.hasOwnProperty('window')){
//callback on window
window[state.window].call(window,state);
}
}
});
in this way, you can specify an optional callback function on the state object when adding to history, then when popstate is trigger, this function would be called with the state object as a parameter.
function pushState(title,url,callback)
{
var state = {
Url : url,
Title : title,
};
if(window[callback] && typeof window[callback] === 'function')
{
state.callback = callback;
}
history.pushState(state,state.Title,state.Url);
}
You could easily extend this to suit your needs.
And Finally says:
I'd have thought the browser would be happy to step back to an entry that was created by a normal request.
I found an explanation of that strange browser's behavior here. The explanation is
you should save the state when your site is loaded the first time and thereafter every time it changes state
I tested this - it works.
It means there is no need in loading your content based on window.location.
I hope I don't mislead.

How to delete a localStorage item when the browser window/tab is closed?

My Case: localStorage with key + value that should be deleted when browser is closed and not single tab.
Please see my code if its proper and what can be improved:
//create localStorage key + value if not exist
if (localStorage) {
localStorage.myPageDataArr = {
"name" => "Dan",
"lastname" => "Bonny"
};
}
//when browser closed - psedocode
$(window).unload(function() {
localStorage.myPageDataArr = undefined;
});
should be done like that and not with delete operator:
localStorage.removeItem(key);
Use with window global keyword:-
window.localStorage.removeItem('keyName');
You should use the sessionStorage instead if you want the key to be deleted when the browser close.
You can make use of the beforeunload event in JavaScript.
Using vanilla JavaScript you could do something like:
window.onbeforeunload = function() {
localStorage.removeItem(key);
return '';
};
That will delete the key before the browser window/tab is closed and prompts you to confirm the close window/tab action. I hope that solves your problem.
NOTE: The onbeforeunload method should return a string.
localStorage.removeItem(key); //item
localStorage.clear(); //all items
There is a very specific use case in which any suggestion to use sessionStorage instead of localStorage does not really help.
The use-case would be something as simple as having something stored while you have at least one tab opened, but invalidate it if you close the last tab remaining.
If you need your values to be saved cross-tab and window, sessionStorage does not help you unless you complicate your life with listeners, like I have tried.
In the meantime localStorage would be perfect for this, but it does the job 'too well', since your data will be waiting there even after a restart of the browser.
I ended up using a custom code and logic that takes advantage of both.
I'd rather explain then give code. First store what you need to in localStorage, then also in localStorage create a counter that will contain the number of tabs that you have opened.
This will be increased every time the page loads and decreased every time the page unloads. You can have your pick here of the events to use, I'd suggest 'load' and 'unload'.
At the time you unload, you need to do the cleanup tasks that you'd like to when the counter reaches 0, meaning you're closing the last tab.
Here comes the tricky part: I haven't found a reliable and generic way to tell the difference between a page reload or navigation inside the page and the closing of the tab.
So If the data you store is not something that you can rebuild on load after checking that this is your first tab, then you cannot remove it at every refresh.
Instead you need to store a flag in sessionStorage at every load before increasing the tab counter.
Before storing this value, you can make a check to see if it already has a value and if it doesn't,
this means you're loading into this session for the first time, meaning that you can do the cleanup at load if this value is not set and the counter is 0.
use sessionStorage
The sessionStorage object is equal to the localStorage object, except that it stores the data for only one session. The data is deleted when the user closes the browser window.
The following example counts the number of times a user has clicked a button, in the current session:
Example
if (sessionStorage.clickcount) {
sessionStorage.clickcount = Number(sessionStorage.clickcount) + 1;
} else {
sessionStorage.clickcount = 1;
}
document.getElementById("result").innerHTML = "You have clicked the button " +
sessionStorage.clickcount + " time(s) in this session.";
Try using
$(window).unload(function(){
localStorage.clear();
});
Hope this works for you
There are five methods to choose from:
setItem(): Add key and value to localStorage
getItem(): Retrieve a value by the key from localStorage
removeItem(): Remove an item by key from localStorage
clear(): Clear all localStorage
key(): Passed a number to retrieve nth key of a localStorage
You can use clear(), this method when invoked clears the entire storage of all records for that domain. It does not receive any parameters.
window.localStorage.clear();
for (let i = 0; i < localStorage.length; i++) {
if (localStorage.key(i).indexOf('the-name-to-delete') > -1) {
arr.push(localStorage.key(i));
}
}
for (let i = 0; i < arr.length; i++) {
localStorage.removeItem(arr[i]);
}
8.5 years in and the original question was never actually answered.
when browser is closed and not single tab.
This basic code snippet will give you the best of both worlds. Storage that persists only as long as the browser session (like sessionStorage), but is also shareable between tabs (localStorage).
It does this purely through localStorage.
function cleanup(){
// place whatever cleanup logic you want here, for example:
// window.localStorage.removeItem('my-item')
}
function tabOpened(){
const tabs = JSON.parse(window.localStorage.getItem('tabs'))
if (tabs === null) {
window.localStorage.setItem('tabs', 1)
} else {
window.localStorage.setItem('tabs', ++tabs)
}
}
function tabClosed(){
const tabs = JSON.parse(window.localStorage.getItem('tabs'))
if (tabs === 1) {
// last tab closed, perform cleanup.
window.localStorage.removeItem('tabs')
cleanup()
} else {
window.localStorage.setItem('tabs', --tabs)
}
}
window.onload = function () {
tabOpened();
}
window.onbeforeunload = function () {
tabClosed();
}
why not used sessionStorage?
"The sessionStorage object is equal to the localStorage object, except that it stores the data for only one session. The data is deleted when the user closes the browser window."
http://www.w3schools.com/html/html5_webstorage.asp
Although, some users already answered this question already, I am giving an example of application settings to solve this problem.
I had the same issue. I am using https://github.com/grevory/angular-local-storage module in my angularjs application. If you configure your app as follows, it will save variable in session storage instead of local storage. Therefore, if you close the browser or close the tab, session storage will be removed automatically. You do not need to do anything.
app.config(function (localStorageServiceProvider) {
localStorageServiceProvider
.setPrefix('myApp')
.setStorageType('sessionStorage')
});
Hope it will help.
Here's a simple test to see if you have browser support when working with local storage:
if(typeof(Storage)!=="undefined") {
console.log("localStorage and sessionStorage support!");
console.log("About to save:");
console.log(localStorage);
localStorage["somekey"] = 'hello';
console.log("Key saved:");
console.log(localStorage);
localStorage.removeItem("somekey"); //<--- key deleted here
console.log("key deleted:");
console.log(localStorage);
console.log("DONE ===");
} else {
console.log("Sorry! No web storage support..");
}
It worked for me as expected (I use Google Chrome).
Adapted from: http://www.w3schools.com/html/html5_webstorage.asp.
I don't think the solution presented here is 100% correct because window.onbeforeunload event is called not only when browser/Tab is closed(WHICH IS REQUIRED), but also on all other several events. (WHICH MIGHT NOT BE REQUIRED)
See this link for more information on list of events that can fire window.onbeforeunload:-
http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
After looking at this question 6 years after it was asked, I found that there still is no sufficient answer to this question; which should achieve all of the following:
Clear Local Storage after closing the browser (or all tabs of the domain)
Preserve Local Storage across tabs, if at least one tab remains active
Preserve Local Storage when reloading a single tab
Execute this piece of javascript at the start of each page load in order to achieve the above:
((nm,tm) => {
const
l = localStorage,
s = sessionStorage,
tabid = s.getItem(tm) || (newid => s.setItem(tm, newid) || newid)((Math.random() * 1e8).toFixed()),
update = set => {
let cur = JSON.parse(l.getItem(nm) || '{}');
if (set && typeof cur[tabid] == 'undefined' && !Object.values(cur).reduce((a, b) => a + b, 0)) {
l.clear();
cur = {};
}
cur[tabid] = set;
l.setItem(nm, JSON.stringify(cur));
};
update(1);
window.onbeforeunload = () => update(0);
})('tabs','tabid');
Edit: The basic idea here is the following:
When starting from scratch, the session storage is assigned a random id in a key called tabid
The local storage is then set with a key called tabs containing a object those key tabid is set to 1.
When the tab is unloaded, the local storage's tabs is updated to an object containing tabid set to 0.
If the tab is reloaded, it's first unloaded, and resumed. Since the session storage's key tabid exists, and so does the local storage tabs key with a sub-key of tabid the local storage is not cleared.
When the browser is unloaded, all session storage will be cleared. When resuming the session storage tabid won't exists anymore and a new tabid will be generated. Since the local storage does not have a sub-key for this tabid, nor any other tabid (all session were closed), it's cleared.
Upon a new created tab, a new tabid is generated in session storage, but since at least one tabs[tabid] exists, the local storage is not cleared
This will do the trick for objects.
localStorage.removeItem('key');
Or
localStorage.setItem('key', 0 );
You can simply use sessionStorage. Because sessionStorage allow to clear all key value when browser window will be closed .
See there : SessionStorage- MDN
This is an old question, but it seems none of the answer above are perfect.
In the case you want to store authentication or any sensitive information that are destructed only when the browser is closed, you can rely on sessionStorage and localStorage for cross-tab message passing.
Basically, the idea is:
You bootstrap from no previous tab opened, thus both your localStorage and sessionStorage are empty (if not, you can clear the localStorage). You'll have to register a message event listener on the localStorage.
The user authenticate/create a sensitive info on this tab (or any other tab opened on your domain).
You update the sessionStorage to store the sensitive information, and use the localStorage to store this information, then delete it (you don't care about timing here, since the event was queued when the data changed). Any other tab opened at that time will be called back on the message event, and will update their sessionStorage with the sensitive information.
If the user open a new tab on your domain, its sessionStorage will be empty. The code will have to set a key in the localStorage (for exemple: req). Any(all) other tab will be called back in the message event, see that key, and can answer with the sensitive information from their sessionStorage (like in 3), if they have such.
Please notice that this scheme does not depend on window.onbeforeunload event which is fragile (since the browser can be closed/crashed without these events being fired). Also, the time the sensitive information is stored on the localStorage is very small (since you rely on transcients change detection for cross tab message event) so it's unlikely that such sensitive information leaks on the user's hard drive.
Here's a demo of this concept: http://jsfiddle.net/oypdwxz7/2/
There are no such the way to detect browser close so probably you can't delete localStorage on browser close but there are another way to handle the things you can uses sessionCookies as it will destroy after browser close.This is I implemented in my project.
if(localStorage.getItem("visit") === null) {
localStorage.setItem('visit', window.location.hostname);
console.log(localStorage.getItem('visit'));
}
else if(localStorage.getItem('visit') == 'localhost'){
console.log(localStorage.getItem('visit'));
}
else {
console.log(localStorage.getItem('visit'));
}
$(document).ready(function(){
$("#clickme").click(function(){
localStorage.setItem('visit', '0');
});
});
window.localStorage.removeItem('visit');
window.addEventListener('beforeunload', (event) => {
localStorage.setItem("new_qus_id", $('.responseId').attr('id'));
var new_qus_no = localStorage.getItem('new_qus_id');
console.log(new_qus_no);
});
if (localStorage.getItem('new_qus_id') != '') {
var question_id = localStorage.getItem('new_qus_id');
} else {
var question_id = "<?php echo $question_id ; ?>";
}
you can try following code to delete local storage:
delete localStorage.myPageDataArr;

Categories

Resources