Starting from Chrome V80, few events like beforeunload, unload etc are getting deprecated. How would we handle such existing events further in JavaScript?
My requirement is to alert when user tries to refresh / reload the page (F5 or ctrl+r) or browser back button, I need to alert and on confirmation, I need to reload or move back. This is in JSF2.2
But the behavior should not effect the functioning in other browsers.
Can someone please help me with this
The beforeunload event will still be usable. What's being changed is the ability to perform sync XHR during page dismissal. The real harmful thing which will be deprecated in the long term is synchronous XHR, since it hurts the user experience. You'll still be able to make use of beforeunload. Getting Rid of Synchronous XHRs specifically mentions this:
Note: We expect to remove support for synchronous use of XMLHTTPRequest() during page unloads in Chrome in version 80, scheduled to ship early in 2020.
There's also information about this specific change in Chrome Platform Status: Disallow sync XHR in page dismissal. There's more information about Chrome 80 in Deprecations and removals in Chrome 80:
Chrome now disallows synchronous calls to XMLHTTPRequest() during page dismissal when the page is being navigated away from or is closed by the user. This applies to beforeunload, unload, pagehide, and visibilitychange.
To ensure that data is sent to the server when a page unloads, we recommend sendBeacon() or Fetch keep-alive. For now, enterprise users can use the AllowSyncXHRInPageDismissal policy flag and developers can use the origin trial flag allow-sync-xhr-in-page-dismissal to allow synchronous XHR requests during page unload. This is a temporary "opt-out" measure, and we expect to remove this flag in Chrome 82.
Note that popups during page dismissal will also be disallowed:
Pages may no longer use window.open() to open a new page during unload. The Chrome popup blocker already prohibited this, but now it is prohibited whether or not the popup blocker is enabled.
Related
Background / use case
I would like to automate some page interactions by pasting a script into my browser console (normally Chrome/Chromium or in my case IE11 because.. don't ask.)
Typical steps in one iteration:
(initial) Visit a page, wait until it is fully loaded.
Fill in form values automatically, trigger some buttons, submit.
Wait for new page after form submission.
Go to 'next page', wait until it is fully loaded, start over with a new set of form values.
The "Visit a page" or "Go to 'next page'" could either happen by clicking a button, or by setting document.location.href explicitly.
The "wait for ..." can take up to 30 seconds in both cases. Not for any good reason, just because.
I am aware (to my current understanding) that the js (event listeners etc) included in a page does not survive a new page load. I am specifically asking about js called form the browser's developer console.
Question
How can I register an event listener from the console for "page load complete" after setting document.location.href, or doing something equivalent?
As mentioned, in my use case I would need to do this with Internet Explorer 11. But I assume people are more familiar with the developer tools in Chromium or Firefox. Any answer that works in one of these browsers is welcome, just mention which browser you tried this with.
Limitations
I do not control the web application where I want to do this, I only control my browser. It also does not look like the developers of said application would be likely to respond to feature requests or wishes.
Perhaps someone will suggest to do this with an iframe. I am not sure this will work. If it does, this would be a different question.
Perhaps someone will suggest some kind of browser simulator tool to use instead of the console. Unfortunately I need/want to make this work on Internet Explorer in a corporate Windows environment with limited privileges. Alternative tools can be mentioned, but there is a reason why I focus on browser console.
I need to implement a feature that checks for changed content before window close and display a predefined warning message if so.
What I did is simply register my handler as follows:
window.addEventListener("beforeunload", checkValueChanged, true);
In the very handler I initiate a synchronous request (using jsf.ajax.request()) to submit all pending data and calculate changes.
The whole solution seems to work pretty well for most cases, but when request takes a little bit longer (300ms?) the browser brutally kills the script without waiting for the response.
It happens only for Chrome (tested on 48.0.2564.116 m) - FF and IE waits for the request to complete. What`s more when I enable developer tools in Chrome it also works.
I suspect that this is an intended Chrome behavior based on a fixed timeout for onbeforeunload handlers execution time designed to protect user from various tricks and hacks on some sites (especially in porno ones :)).
My question is: have you ever encountered and handled somehow such situation? Is this "feature" documented somewhere in Chrome documentation or maybe its a bug? If its a feature can it be locally reconfigured or disabled?
I will be grateful for any hints :)
I am working on an extension for Chrome that utilizes a native messaging host. My background.js registers a listener immediately to process all onBeforeRequest events (i.e., all requests) and pass them on to the native helper application. This is all well and good when a page is visited after Chrome has started up, but when I click a URL that launches Chrome, my listener does not fire.
Here is the basic structure of the listener at the top of my background.js:
chrome.webRequest.onBeforeRequest.addListener(function (details) {
alert('forwarding request!');
chrome.runtime.sendNativeMessage('<extension name>', { url: details.url });
}, { urls: ['http://*', 'https://*'] }, ['blocking']);
Obviously, there are conditions in place that determine whether to pass off the request and block it in Chrome, but they are not relevant here. Even without the sendNativeMessage bit, I cannot produce an alert for the URL that is clicked to launch an instance of Chrome.
Any clever ways to register this listener before the first request at startup goes through?
You can try giving your extension the background permission:
Makes Chrome start up early and and shut down late, so that apps and extensions can have a longer life.
When any installed hosted app, packaged app, or extension has "background" permission, Chrome runs (invisibly) as soon as the user logs into their computer—before the user launches Chrome. The "background" permission also makes Chrome continue running (even after its last window is closed) until the user explicitly quits Chrome.
This way the Chrome process and extensions will be loaded before you click any URL. The user can still circumvent this by explicitly killing the Chrome process.
As a side note, keep in mind that the response from your onBeforeRequest listener needs to be synchronous if you want to block a request, so you can't base the decision to block on the response from a native messaging host.
One way to solve the problem is to use the chrome.declarativeWebRequest API to declaratively register a webRequest listener. The disadvantage of this API is that it is only available to Chrome users on the beta and dev channel at the moment, and less flexible than the webRequest API (the rules are declarative, so you cannot make runtime decisions about request handling that are not supported by the DWR API).
Another way to work around the problem is to use chrome.tabs.query to find tabs that had been opened before the extension was launched.
Here's the situation:
I have a web-based ticket application, multiple users.
One problem that might occur (and does happen in the old version I'm replacing) is that user1 opens a ticket, edits it, and saves it. But while he was editing it, user2 also opened and saved the ticked. The changes user2 made will be lost/overwritten by user1.
To prevent this I implemented a locking mechanism, it's fairly simply:
On opening a ticket the PHP script checks for existing locks.
If it doesn't find any, it locks & opens the document.
In JS, setTimeout() and an XmlHttpRequest call to unlocks the ticket after 10 minutes (works w/o problems).
I also set an unload event to unlock the ticket when closing/moving away from the window/tab
The problem sits in step 4: The unload event (& it's friend beforeunload) just doesn't work well enough to implement this reliably (for this feature to have any serious meaning, it needs to be reliable), many browsers don't always fire it when I would like it to be fired (Like pressing back button, hitting F5, closing tab, etc. This varies per browser)
The only alternative I can come up with is using a setTimeout() and XmlHttpRequest() call to a php script to tell it the page is still open. If this "heartbeat" monitor fails we assume the user moved away from the ticket and unlock the document.
This seems horribly inefficient to me and quickly leads to many requests to the server with even a few users.
Anyone got a better idea on how to handle this?
It needs to work in IE8+ and other modern browsers (ideally, Firefox, Webkit, Opera). I don't care about IE6/IE7, our organization doesn't use those).
Using heartbeat pings via XHR is the way to go. Depending on the use case you might also want to send them after the user stopped typing in a field instead of every x seconds - this would ensure the page being kept open but inactive would not keep it locked.
If you send those XHRs after the user stopped typing, use one of the keydown/up/press events and a debounce / throttle script to send the request only when the user stops typing for e.g. 5 seconds and one every x seconds (in case it's likely enough the user will be typing for a long time).
Maybe it's not the best solution, but it's worth looking into it : websockets.
You could establish a connection with the server at page load and when the connection fails (ie the client does not respond to the ping), you can unlock the ticket.
Using something like socket.io ensures you that this procedure will work even on ie8.
The main advantage is that you do not send a request every n seconds, but the server sends you a ping every n seconds and you don't have to care about unload/beforeunload events. If the client doesn't respond to the ping, unlock the ticket.
The main disadvantage is that you need a server to handle all your websocket connections, which can be done in almost any server-side language, but it can be a bit harder than a simple web-service (in case of xhr polling)
Implementing ajax heartbeats or unload handlers to unlock the document automatically is tricky.
You problem is that even if you have support for beforeunload in all browsers that you target, it still might not be called if the browser crashes or the user falls asleep.
Look at how webdav works. You explicitly aquire a lock before you start edit, then you save and release the lock explicitly.
Other users can see who has acquired a lock and admins can release locks that has been left behind by accident.
I am working on a multiplayer chess game as a Facebook app.
If one player leaves the game by closing the browser the other player should get a notification. So if one player closes the Browser, a unlink function should be called to unlink the player. This works fine with onunload outside Facebook.
The problem is, that the Facebook apps are loaded in iframes and the onunload event doesn't work there.
So I need a way to call a function inside an iframe when a user is closing the browser.
This is probably not the answer you are looking for but "logging off" on unload will never work reliably. For an extreme example, consider the case where the browser crashes or is killed via the Windows task manager. So you better implement an additional mechanism to detect whether a user left. Typically this is done by sending a request to the server periodically. If this request isn't received for a significant time (meaning something that cannot be caused by a slow connection or other hiccups) you unlink the user.
That said, I tested Firefox 4 and MSIE 8 and both correctly fire unload event on the frame if the tab or the browser is closed. Chrome 12 doesn't do that, that's probably the browser you have been testing with. I consider it a Chrome bug.