How to check if a web page is open or not? - javascript

I have a website where users message each other through another website. My problem is that everytime user click on message item this action opens a new tab.
Having a lot of conversations makes this quite annoying, especially when using on a smartphone.
Is there any way to check if the website for texting is open?

If you are using window.open() you can add the target parameter.
A string, without whitespace, specifying the name of the browsing context the resource is being loaded into. If the name doesn't identify an existing context, a new context is created and given the specified name. The special target keywords, _self, _blank, _parent, and _top, can also be used.
example
window.open("https://www.mozilla.org/", "mozillaTab");

You are looking for postMessage. Synapsis:
postMessage(message, targetOrigin, transfer)
message is the actual message you want to send
targetOrigin specifies which domain is the target
transfer is a sequence of transferrable objects that are transmitted with the message
So, what you really want is to have this conversation:
Page1: are you there?
Page2: yes
or
Page1: are you there?
... (timeout)
I will call Page2 the page whose existence we wonder about and Page1 the page which wonders about Page2's existence.
First of all, you need a message handler at both Page1 and Page2. Synapsis:
window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;
//check event.data and see what happens
}, false);
On Page 2, your message handler will need to check whether the message asks about its existence and calls postMessage('Yes, I am here', event.origin); if so. Page1, on the other hand initiates the messaging by calling postMessage('Are you there?', theurl); (where you need to replace theurl with your value). Now, Page1 expects a message. If the message arrives, then Page2 exists. If not, then after a timeout you need to handle the nonexistence of Page2. So, you will have something like this at Page1:
var wasFound = false;
postMessage('Are you there', theurl);
setTimeout(function() {
if (!wasFound) {
//The page needs to be opened
}
}, 500);
Naturally, you will need to set wasFound to true when you receive a message from Page2 and you will need to make sure that the message handler sees the same wasFound variable that your timeout checks for.

Related

How to lock a website with password in google?

I'm trying to lock youtube for reasons I'm not going to detail and I tried this script, but it only asks for the password. Nothing else happens, not even the console.log(). Any suggestions?
var pass = prompt("YouTube is locked. Password to unlock");
if (pass != "password") {
document.getElementById('watch7-content').innerHTML = location.replace("google.com");
console.log('wrong');
}
What I'm trying to do is ask for the password with prompt() and if it's not the password it'll redirect to google.com. It uses the video player as a reference for the url replacement, but i don't know if it works. Again, I don't think it's even working because it won't even console.log()...
location.replace does perform a reload the page and this is the case why your console.log is not visible in console. If you move console.log on top of location.replace and you preserve console history (so it is not cleared between reloads) you will see it is executed successfully.
Also make sure to use full url with location.replace:
location.replace('https://google.com')

React : Handle multiple browser(s), browser tabs to restrict duplicate operations

I have a button Submit when clicked performs some operation calling an API. Post click, the button is disabled or basically the initial state of the button and the operation is changed.
I have two or multiple browser tabs which shows same screen of Submit. If in any one of the tab, the Submit operation is performed, the other tabs should show the updated version. The other tabs should show the disabled version and should not show the initial state.
How do I achieve this? I am using React, JS
#1 Data duplication MUST be restricted at the server side.
I would recommend some cache like node-cache. Node-cache will having scalability issues, so better to go with redis. (The logic should be smt. like: If the form has submited with the user_id, or with form_id, you can create a cache for that, and if you proceed it, store it in the db, other case throws an error. On the other browser you must validate before the submit if the unique_id neither in the cache nor in the db. If exists, you can throws an error in the nr.2 browser.
#2 If you want to disable the button, you have to use websockets
If you're looking for a client-only solution, here is a great article about sharing state between browser tabs. The limitation is that it won't work on different browsers/machines.
The best way to handle this from a UI/UX perspective is to use validation. If User A clicks submit, then User B clicks submit from a different browser or tab, an error should be displayed to User B indicating that "This action has already taken place".
That being said, what you are trying to achieve is possible.
One way is by using a WebSocket. A WebSocket is a persistent connection between the client and server, that allows bi-directional communication.
The page with the submit button in your React app would be a "subscriber" to some websocket channel. When the submit button is clicked for the first time(it doesn't matter from where), a message can be "published" from a WebSocket server to ALL subscribers, regardless of the browser or tab being used.
Basically, you would add an onMessage handler in your React app where you can disable the submit button when a specific message is received.
I don't know what tech you are using on the server side, but for a WebSocket server, there are many options out there. For the React app, there is react-websocket which is straight-forward to use.
you can do it in client-side
const Form = () => {
const [buttonDisabled, setButtonDisable] = useState(false);
// first tab fire
const onSubmit = () => {
.
.
.
localStorage.setItem("formSubmited", "true");
};
useEffect(() => {
const disableButton = (e) => {
if (e.storageArea.formSubmited) {
setButtonDisable(true);
}
};
// second tab fire
window.addEventListener("storage", disableButton);
return () => {
window.removeEventListener("storage", disableButton);
};
}, []);
.
.
.
};

Java script, PHP

I have a scenario where I need to execute a logout function in php, this function deletes the user from DB and informs another application through sockets. This function should be called when the user closes the browser or tab. I have tried various scenarios posted by others and nothing seems to work in chrome(Version 57.0.2987.110) and firefox.
Following is the examples I tried along with links,
My sample Code
<script type="text/javascript">
var str = 'delete';// this will be set to 'Apply' if the form is submitted.
function logout(){
location.href = 'Logout.php';
}
function pageHidden(evt){
if (str==='delete')
logout();
}
window.addEventListener("pagehide", pageHidden, false);
</script >
Examples I tried....
// 1st approach
//window.addEventListener("beforeunload", function (e) {
/// var confirmationMessage = "Do you want to leave?";
// (e || window.event).returnValue = confirmationMessage;
// return confirmationMessage;
// });
// 2nd approach
// window.onbeforeunload = myUnloadEvent;
// function myUnloadEvent() {
// console.log("Do your actions in here")
// }
// 3rd approach
$(window).on('beforeunload', function() {
return 'Your own message goes here...';
});
checked the following urls
1. window.onunload is not working properly in Chrome browser. Can any one help me?
2. https://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/ - I followed this approach. Tried some other approaches as well.
3. I can't trigger the unload event in Chrome etc....
Any help is much appreciated, because if the user closes the browser an entry remains in the DB and this is not allowing any new user to login.
You shouldn't rely on JavaScript for sever-side code. It's actually entirely possible to achieve what you're looking for, purely with PHP. Just make sure to 'kill' the session before starting it:
session_set_cookie_params(0);
session_start();
session_set_cookie_params(0) will tell the browser that any exisiting session should only exist for another 0 seconds. Essentially, this means that a user will automatically 'log out' immediately. This way, you don't have to rely on client-side code, which is susceptible to all measure of interrupts such as power outages.
Hope this helps! :)
The correct way to logout is related to how they are logged in.
In PHP, the login state is typically managed by sessions. By default the timeout is 24 minutes of inactivity, but you can easily reduce it.
When a user logs out, you typically reset one or more session variables, and, while you’re at it, kill off the current session, and delete the session cookie.
However, you cannot rely on a user to log out, and many typically just wander off. This is why there is always a relatively short timeout on sessions.
If you want to automatically logout when the tab is closed, you will need JavaScript to intercept the process with window.onbeforeunload and then use Ajax to send the logout to the server.
As regards the database, you normally do not record the login state in the database. You may record the login time, and if you like, the logout time, but remember that may be never.

Data stored in localStorage isn't there when I redirect

I have Javascript on a page that sets localStorage data:
localStorage.setItem('blah', 1);
Then, I have code that will redirect to another page on a button click.
On the other page I try to access the item in localStorage, but I get Uncaught TypeError: Cannot read property 'blah' of null 30% of the time. How come localStorage isn't saving each time?
Am I missing something?
On Current Page
localStorage.setItem('blah', 1);
$('.btn').on('click', function() { window.location.href = 'http://example.com/signup?redirect=/chkout'; });
On Redirect Page
localStorage.getItem('blah', 1); ==> null
This might happen because
The tab/window is in incognito / private surfing mode
The browser is configured to track no history at all
The item was set on another port or scheme (of the same domain) (e.g. http://foo.com instead of https://foo.com)
From the W3C specification:
The user agent may throw a SecurityError exception and abort these steps instead of returning a Storage object if the request violates a policy decision (e.g. if the user agent is configured to not allow the page to persist data).
If the Document's origin is not a scheme/host/port tuple, then throw a SecurityError exception and abort these steps.
The localStorage data should persist, by several documentations. There may be a case when your localStorage data gets overwritten by some other operation. You can try to debug this by adding following eventListener:
window.addEventListener("storage", function(data) {
console.debug(data);
}, false);
This should log the data, every time the storage is accessed.

Removing someone from a user hash on navigating away from a page / page close

I'm building a Node.js / Socket.io project.
I have a hash of Users based on their websocket id. When a user makes the following request i'd like to add them to a group of users viewing that page.
app.get('/board/:id', function(req, res){}
I'd like to keep something like
Browsing = {
username : id,
username : id,
...
}
However i'm unsure how to remove a user lets say if they navigate off the page. Is there some kind of function that gets called upon page leave?
Partial Solution:The following seems to do the trick on Chrome:
$(window).unload(function(){
var username = $('#username').text();
var pid = currentProject;
var data = {
username: username,
id : pid
}
socket.emit('leaving-page', data);
})
... Is there some kind of function that gets called upon page
leave? ...
Yes, but it is not reliable.
The way the people keep track of who is online and who isn't, is usually like this:
Add the time when the user last refreshed/visited a page
set a limit to you consider them offline
You could intercept the event which corresponds to leaving a page. There are several ways to do it, have a look at the following links and let me know if any suits your needs and if I can answer any more explicit questions about them:
Intercept page exit event
Best way to detect when a user leaves a web page?
jquery unload
with the last link you could do something like this:
$(window).unload(function() {
//remove the user from your json object with delete json_object[key];
});
Hope this helps.
Since you're using Socket.io, the server will know when the user has left the page because the socket will be disconnected. Simply listen for the disconnect event.
io.sockets.on('connection', function (socket) {
...
socket.on('disconnect', function () {
// The user on `socket` has closed the page
});
});
Better yet, take advantage of namespaces and let Socket.io handle all of the connection/disconnection (it's doing it anyway -- no need to duplicate effort).
On the client,
socket = io.connect('http://example.com/pagename');
pagename need not point to a valid URL on your domain – it's just the namespace you'll use in the server code:
io.sockets.clients('pagename')
Gets you all of the clients currently connected to the pagename namespace.

Categories