window.close does not work in a way that you might think
By: Santhosh Raju
Tags: HTML, JavaScript, Window, Close

For once I thought that window.close Javascript API was fairly a simple one to implement, until one of my colleague asked me for help.

If you think that I’m overthinking on such a fairly simple API, well you might be surprised if you do not already know what I’m talking about.

For starters let’s define what the API actually meant, it simply means to close a current window or tab on the browser the user is interacting with, programmatically. This API gives you the ability to close the window via your code.

function closeMyWindow() {

window.close();

}

Calling this function either by invoking the function or binding it to a DOM event should result in what we might think, hum…?

Even I had the same assumption, but unfortunately it does not work the way we might think it should work!!!

So why does it not work ?

If you check the MDN docs, they clearly mention window.close method can only be called by a window that were opened by a script using window.open or else we get a error on the console Script may not close window that were not opened by script.

According to specs (which is very difficult to read BTW), is that a window can be closed only if it’s browsing context — the Document object presented to the user — is derived from a top level browsing context / parent browsing context (reason for opening with window.open ), so the session.history is not lost by presenting a single Document object. They do not have any intension of preventing XSS while designing this API, at least that is what I read from the specs, so do not think this is for preventing XSS attacks.

So how to implement it ?

Let me give you the same exact scenario we solved in our application.

On page A, we have a button called “publish”. On click of it we open the publish preview page, let’s say page B, on a new tab.

On page B, there are two buttons “Publish” and “Cancel”, on click of cancel it should close the window.

Contents of page A, let’s call it “index.html”

<!doctype html>

<head>

<title>Jupyter notebook</title>

<script>

function openit(){

window.open(location.origin + '/child.html', '__blank');

}

</script>

</head>

<body>

<h1>Jupyter notebook instance</h1>

<button onclick="openit();">kh publish</button>

</body>

</html>

Contents page B, let’s call it “child.html”

<html>

<head>

<title>Notebook edit</title>

</head>

<body>

<h1>Notebook edit page</h1>

<button>Publish</button>

<button onclick="window.close();">Cancel</button>

</body>

</html>

That’s it, pretty simple right!!! Now you know a concept that might confuse you at first.

On a side note, our problem had a slight difference. Both the pages A and B were served on two different addresses, so we had to change the location.origin to the physical address serving page B. Which in this case proves that the design of the API was not to prevent cross site attacks.

Thank you so much for reading, as always I request you to share this to your friends and colleagues and across your channels. So this reaches to anyone who is facing a similar situation.

My intention is same as my motive “Knowledge is meant to be shared”, so please share it.

References