Can I force the sending of a 'CLOSE' signal to my server when a tab directed at my website is closed?
(thinking it might be possible with a Javascript alert on close-tab signal)
Hey your looking for the html window attribute onunload so for example < body onunload="javascriptfunction2server()"> will run your javascript function when a tab/window is closed by user (or directed to new page)
Related
Use case
Existing web page / URL is opened from a 3rd party app. Upon completion of the work on the web page, it is expected to close
itself.
Javascript does not allow it using window.close() or alike, ref.
window.close and self.close do not close the window in Chrome
Browser limitation (Firefox/Chrome) is well documented and explored over the past years. For the given use case, per my understanding closing of a browser tab can only be achieved from a background script, calling chrome.tabs.remove() API.
Browser extension
The approach that seemed logical to me is using the following artifacts.
content.js
document.addEventListener("myCloseTabEvent", function(e){
console.log("[content] originating domain: " + this.domain);
// Prepare message for background script
var myMsgContent = {
type: "myAction",
value: "CloseBrowserTab"}
browser.runtime.sendMessage(myMsgContent);
}, false);
background.js
chrome.runtime.onMessage.addListener(
function(msgData, sender, sendResponse) {
if (msgData.type == "myAction" && msgData.value == "CloseBrowserTab") {
chrome.tabs.remove(sender.tab.id);
} else {
console.log("[background] No action because !(myAction && CloseBrowserTab)");
}
});
Changes to web page to raise the new event
function mySendEvent() {
const myEvent = new Event("myCloseTabEvent"); // OR CustomEvent()
// Dispatch the event
document.dispatchEvent(myEvent);
}
In summary, the following happens:
The web page loads
Content script adds the event listener for a custom event myCloseTabEvent
Background script adds an onMessage listener using chrome.runtime.onMessage.addListener()
Once all work is done on the page, existing Javascript code dispatches the custom event by calling mySendEvent().
Content script runs its listener function(e), sending a message to the background script.
Background script onMessage listener function(msgData, sender, sendResponse) uses the sender object to determine the tabId, and closes the browser tab using chrome.tabs.remove(sender.tab.id);
Questions
In concept, is this approach the best option we have to achieve the goal of closing the browser tab? Would there be any better ways of achieving the same?
A background script is require to be able to close the tab (correct me if I'm wrong here). Therefore the browser extension cannot be restricted to be active only on a specific set of domains using content_scripts -> matches. What best practices exists to restrict the functionality of the browser extension like this to specific domains? (domain names are known to the users of the extension, but not while packaging the artifacts). This is especially is of interest, to prevent other (malicious) web pages from closing them selves by sending the same message to the background script of the extension.
So I've been trying to write a script that needs to open a browser window to do google oauth. Now the problem is I can use open to open the browser window, but I can't find a way to close it after the auth happens. It just stays there.
i'm not sure this what your asking, but you can do this by sending the response to the page like code shown below.
router.get('/yourpage',(req, res) => {
res.send("<script>window.close();</script > ")})
so basically when your page gets opened this will send the close script from the server-side to the client by instructing close the window.
I have a iframe in a page.
After i successfully send data to server within iframe, the server responds with next URL to open , i want to open the next URL in a new tab or in the parent window.
The Problem i am facing is, the browser treats it as a popup and blocks it.
In chrome it is treated as pop up and in safari it doesn't do anything.
The iframe is pointing to iframe (written in REACT)
The parent URL is main page.
Here is the part of the code that s causing error.
this.props.dispatch(actions.init_db(vals, (error,data)=>{
this.setState({loading:false})
if(error){
this.setState({error:error});
}else{
url=data.next_url;
var win=window.open(url);
win.focus();
}
}));
Basically actions.init_db() calls an ajax function that writes the value to the server.
The server than responds with error or data.If no errror, the data contains Next URL and i want to open the URL.
Any Suggestion or alternate to this solution is highly appreciated.
You can't. If you call window.open from code that isn't running in direct response to a user action (such as a click), it's likely to get blocked by the popup blocker of the browser. The solution is to make sure you're running that code in direct response to a user action. So for instance, when you have the URL from the server, show a div on the page with the link in it for the user to open themselves.
I am using C# and asp.net to launch a webpage that I am passing parameters to. That works well! I come from a Windows.Forms background so please forgive me if I am trying to achieve the impossible. What I would like is set the Visibility property of the program (either IE or chrome) to false so the user never sees that a webpage is being launched. I have been using this JS function to close the page, but it seems that the page must completely load before closing which sometimes can take a few seconds.
Does asp.net have the capability to achieve such? And this is my JS code I have been using
string close = #"<script type = 'text/javascript'>
window.returnValue = true;
window.close();
</script>";
base.Response.Write(close);
If you don't want the User to see the page, I assume you just want to post some information to the page. In that case, make an HTTP request via c# code, instead of opening the webpage up in a browser.
On the Project Properties page, Web tab, Start Action section, click the radio button for "Don't open a page. Wait for a request from an external application".
Is it possible to open a new window or tab via javascript in Windows Phone 7 browser?
window.open does not appear to be supported nor does target='_blank'.
Am I missing something here? This basic feature works just fine on iphone and android.
Any ideas on how I can get this working in Windows Phone 7?
On Windows Phone 7 this is not possible programmatically. It's all in the users hand.
To cite a Microsoft employee:
"A user can open a link in a new Tab by tapping and holding the link to
get the context menu but an anchor or scripts request to target a new
window is ignored.
There are several reasons for this:
Cross-window communications are not supported.
Windows Phone only has one instance of the
browser so new "windows" have to be opened as Tab's.
The browser experience is full screen so the user has no good visual cue that they
have moved to a new Tab unless they explicity request it.
Navigating "back" in a new Tab exits the browser which would be
confusing to the user if they did not know a new Tab was created."
If you are trying to add this feature for in-ap browser control, I can suggest you one way.
You have to inject a java-script on every webpage the browser control is able to load the page successfully. In the java-script use window.extern.notify to invoke the ScriptNotify function in your code behind. On the detection of the appropriate message create a new instance of browser control and add it to an array or list. Thereby you can emulate the new tab feature for in-app browser control.
the JS code to be injected may be like this String NEW_TAB_FUNCTION = "window.open = function(__msg){window.external.notify('addnewtab');};";
Which can be injected using browser.InvokeScript("eval", NEW_TAB_FUNCTION);
In ScriptNotify check for addnewtab (keep IsScriptEnabled = True)
void WebBrowser_ScriptNotify(object sender, NotifyEventArgs e)
{
if (e.Value == "addnewtab")
{
//do work here
}
}
Note that I have overridden the window.open function in the JS with a function which will be injected every time on a new webpage in order to get notified of user input.
Also note this works only for WebBrowser Control and not external browser.
My workaround this issue is simple:
window.open
returns null if failed, so in that case I open it in the same window:
var win = window.open(href, '_blank');
if(!win || win==null){
window.location.href = href;
}else{
win.focus();
}
which is a good practice to have a fallback anyway...