Change window.location.href in Firefox without closing websockets - javascript

I am currently trying to trigger a file download using following code in Javascript:
window.location.href = downloadUrl;
That works fine in Chrome, IE and Edge, but Firefox unloads the page due to the new URL and hence closes all opened websockets. I know that this is an odd mannerism of FF, but is there any workaround which I can use?
It would work with window.open(downloadUrl); and closing the new tab after a certain timeout, but I would like to prevent opening a new tab just for triggering the download.
Any help would be appreciated, thanks.

After a lot of researching and experimenting I found the following solution:
Create a link in JavaScript with the download attribute, click it and remove it after some time (I am using ExtJs):
var a = document.createElement("a");
document.body.appendChild(a);
a.style = 'display: none';
a.href = downloadUrl;
a.download = 'test.zip';
a.click();
Ext.defer(function(link) {
document.body.removeChild(link);
}, 200, this, [a]);

Just stumbled on this issue. When user clicks a link (including 'download' one), browser believes he is leaving current page and closes websocket (this is likely reasonable). Opening link by Javascript onclick event (or window.open and so on) doesn't help. Setting target="_blank" helps, but creates uncomfortable blink at the moment of click. Finally I came up with the following:
<iframe src="about:blank" name="iframe_a" class="ws_keep_conn"></iframe>
Click this
CSS
.ws_keep_conn {position: absolute; left: -9999px; visibility: hidden;}
That's all, websocket lives, smooth behavior with no blink!

Related

maps.apple.com search does not open apple maps [duplicate]

I've build a web page that let's you select a page name from a drop down list and then transfers the browser to that page. The code that does the transfer is
if (url){
window.open(url, '_blank');
}
where "url" is the page selected.
A console log just before the window.open line prints something like:
executing: window.open(http://www.mywebsite.com/44/threats.html, '_blank')
and then the browsers opens the page in a new tab.
This works fine on Windows 7 for all the browsers, including Safari.
On an iMac it works for Firefox but not for Safari.
Does anyone know why iMac/Safari won't do this?
Safari is blocking any call to window.open() which is made inside an async call.
The solution that I found to this problem is to call window.open before making an asnyc call and set the location when the promise resolves.
var windowReference = window.open();
myService.getUrl().then(function(url) {
windowReference.location = url;
});
Using setTimeout
Wrapping your window.open(url, '_blank') line of code in the async function with a setTimeout works as well,
setTimeout(() => {
window.open(url, '_blank');
})
setTimeout code runs on the main thread, instead of the asynchronous one.
Tested in Chrome and Safari.
To use window.open() in safari you must put it in an element's onclick event attribute.
For example:
<button class='btn' onclick='window.open("https://www.google.com", "_blank");'>Open Google search</button>
You can't rely on window.open because browsers may have different policies. I had the same issue and I used the code below instead.
let a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = <your_url>;
a.download = <your_fileName>;
a.click();
document.body.removeChild(a);
Taken from the accepted answers comment by Steve on Dec 20, 2013:
Actually, there's a very easy way to do it: just click off "Block popup windows" in the iMac/Safari browser and it does what I want.
To clarify, when running Safari on Mac OS X El Capitan:
Safari -> Preferences
Security -> Uncheck 'Block pop-up windows'
window.location.assign(url) this fixs the window.open(url) issue in ios devices
Open link in a new tab, programatically with JavaScript for: safari, mobile safari and other browsers:
const link = 'https://google.com';
const a = document.createElement("a");
a.setAttribute('href', link);
a.setAttribute('target', '_blank');
a.click();
There's a setting in Safari under "Tabs" that labeled Open pages in tabs instead of windows: with a drop down with a few options. I'm thinking yours may be set to Always. Bottom line is you can't rely on a browser opening a new window.
This should work: window.location.assign(url);
Usually it is important to save the state, before leaving the page, so have this in mind as well.
The correct syntax is window.open(URL,WindowTitle,'_blank') All the arguments in the open must be strings. They are not mandatory, and window can be dropped. So just newWin=open() works as well, if you plan to populate newWin.document by yourself.
BUT you MUST use all the three arguments, and the third one set to '_blank' for opening a new true window and not a tab.

How to open an url and download without being block

I have something like this:
<a
onClick={e => { getDownloadLink()
.then(url => window.open(url)) }}>Download</a>
the getDownloadLink method have to first POST to get a url and then trigger the download by window.open(url),but I found that the browser will block the window.open behavior. How can I prevent that?
I see a lot of questions similar in stackoverflow, but I still didn't find a method to solve my problem. And I found that the aws s3 page do something similar, the page will not being blocked by browser. So... I think there must be some method to handle this.
Don't use window.open, just make the browser do what it already knows to do with HTML: build a link anchor, then click it.
// create an temporary, invisible link and open it in a new tab
function openURL(url) {
var a = document.createElement("a");
a.setAttribute("target", "_blank");
a.href = url;
a.style.display = "none";
// you can't click a link unless it's part of the document:
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
This way you're telling the browser to just "open a link the normal way", and it'll happily do so instead of blocking questionable APIs that have a history of being used for popups and other questionable purposes.

Open Base64 in new tab

I have a Base64 encoded document which can be PDF file or image.
I would like to create a button in HTML5 page that opens this base64 in a new tab (or new page it does not matter)
I found this code can do the trick :
<a href="http://chriscoyier.net"
onclick="window.open(this.href); return false;"
onkeypress="window.open(this.href); return false;">
This link will open in new window/tab
</a>
It works well.
But when I replace the http link with
href="data:application/octet-stream;base64,/9j/4A.."
then the file is downloaded but not displayed in browser.
Your MIME type is set to 'application/octet-stream', which will generally be downloaded and not displayed (depending on browser and system settings). If you are trying to load browser-displayable content, then you should use a more appropriate MIME type for your content so that it displays inline and does not get downloaded.
Please note: As of Chrome 60 and an upcoming version of FireFox (although it appears FireFox will still support images), data URIs cannot be opened in the top-level frame of the browser (and it was never supported in IE/Edge), but they can be opened in iframes and img elements.
The workaround below is tested and working in the latest version of the above browsers. This could also be rewritten with an img tag to display an image.
<button id='btnDownload'>Download</button>
document.getElementById('btnDownload').addEventListener('click', function(){
var w = window.open('about:blank');
setTimeout(function(){ //FireFox seems to require a setTimeout for this to work.
w.document.body.appendChild(w.document.createElement('iframe'))
.src = 'data:application/octet-stream;base64,SWYgSSBoYWQgYSBuaWNrbGUgZm9yIGV2ZXJ5IHRpbWUgSSBoYWQgYSBuaWNrbGUsIEknZCBoYXZlIGVhdGVuIHR3aWNlIGFzIG1hbnkgcGlja2xlcy4=';
}, 0);
});
If, however, your intention is to just download the content (contrary to the stated intent in the question, but applicable to 'application/octet-stream' content in general), this should suffice:
<a href='data:application/octet-stream;base64,SWYgSSBoYWQgYSBuaWNrbGUgZm9yIGV2ZXJ5IHRpbWUgSSBoYWQgYSBuaWNrbGUsIEknZCBoYXZlIGVhdGVuIHR3aWNlIGFzIG1hbnkgcGlja2xlcy4=' download>Download this</a>
Tested on chrome and Firefox, just add the base64 value into the href attribute works (without onclick & onkeypress events). Just like that :
<html>
<body>
test
</body>
</html>
I am adding the answer to my question based on Aaron's answer:
document.getElementById('btnDownload').addEventListener('click', function(){
var w = window.open('about:blank');
setTimeout(function(){ //FireFox seems to require a setTimeout for this to
work.
w.document.body.appendChild(w.document.createElement('iframe'))
.src = $this.attr('href');
w.document.getElementsByTagName("iframe")[0].style.width = '100%';
w.document.getElementsByTagName("iframe")[0].style.height = '100%';
}, 0);
});
<a href="aHR0cHM6Ly93d3cuc3dpdGNoLXRvcnJlbnRzLmNvbS9kb3dubG9hZC80MTMvU3VwZXIlMjBTbWFzaCUyMEJyb3MlMjBVbHRpbWF0ZS50b3JyZW50"
onclick="window.open(this.href); return false;"
onkeypress="window.open(this.href); return false;">
This link will open in new window/tab
</a>

window.open(url, '_blank'); not working on iMac/Safari

I've build a web page that let's you select a page name from a drop down list and then transfers the browser to that page. The code that does the transfer is
if (url){
window.open(url, '_blank');
}
where "url" is the page selected.
A console log just before the window.open line prints something like:
executing: window.open(http://www.mywebsite.com/44/threats.html, '_blank')
and then the browsers opens the page in a new tab.
This works fine on Windows 7 for all the browsers, including Safari.
On an iMac it works for Firefox but not for Safari.
Does anyone know why iMac/Safari won't do this?
Safari is blocking any call to window.open() which is made inside an async call.
The solution that I found to this problem is to call window.open before making an asnyc call and set the location when the promise resolves.
var windowReference = window.open();
myService.getUrl().then(function(url) {
windowReference.location = url;
});
Using setTimeout
Wrapping your window.open(url, '_blank') line of code in the async function with a setTimeout works as well,
setTimeout(() => {
window.open(url, '_blank');
})
setTimeout code runs on the main thread, instead of the asynchronous one.
Tested in Chrome and Safari.
To use window.open() in safari you must put it in an element's onclick event attribute.
For example:
<button class='btn' onclick='window.open("https://www.google.com", "_blank");'>Open Google search</button>
You can't rely on window.open because browsers may have different policies. I had the same issue and I used the code below instead.
let a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = <your_url>;
a.download = <your_fileName>;
a.click();
document.body.removeChild(a);
Taken from the accepted answers comment by Steve on Dec 20, 2013:
Actually, there's a very easy way to do it: just click off "Block popup windows" in the iMac/Safari browser and it does what I want.
To clarify, when running Safari on Mac OS X El Capitan:
Safari -> Preferences
Security -> Uncheck 'Block pop-up windows'
window.location.assign(url) this fixs the window.open(url) issue in ios devices
Open link in a new tab, programatically with JavaScript for: safari, mobile safari and other browsers:
const link = 'https://google.com';
const a = document.createElement("a");
a.setAttribute('href', link);
a.setAttribute('target', '_blank');
a.click();
There's a setting in Safari under "Tabs" that labeled Open pages in tabs instead of windows: with a drop down with a few options. I'm thinking yours may be set to Always. Bottom line is you can't rely on a browser opening a new window.
This should work: window.location.assign(url);
Usually it is important to save the state, before leaving the page, so have this in mind as well.
The correct syntax is window.open(URL,WindowTitle,'_blank') All the arguments in the open must be strings. They are not mandatory, and window can be dropped. So just newWin=open() works as well, if you plan to populate newWin.document by yourself.
BUT you MUST use all the three arguments, and the third one set to '_blank' for opening a new true window and not a tab.

How to use target in location.href

I am currently developing a web application where I need to open a popup window to show a report. The problem is that some versions of explorer don't support the window.open javascript function, so when this is the case I catch the error and open the new url with location.href. Here the code:
try {
window.open(url, "","width=1002,height=700,location=0,menubar=0,scrollbars=1,status=1,resizable=0")
} catch(e) {
location.target = "_blank";
location.href = url;
}
The problem is that the location.target is not working and I would like to know if there is a way to specify the target of the location.href so it can be opened in a new tab.
try this one, which simulates a click on an anchor.
var a = document.createElement('a');
a.href='http://www.google.com';
a.target = '_blank';
document.body.appendChild(a);
a.click();
You can use this on any element where onclick works:
onclick="window.open('some.htm','_blank');"
The problem is that some versions of explorer don't support the window.open javascript function
Say what? Can you provide a reference for that statement? With respect, I think you must be mistaken. This works on IE6 and IE9, for instance.
Most modern browsers won't let your code use window.open except in direct response to a user event, in order to keep spam pop-ups and such at bay; perhaps that's what you're thinking of. As long as you only use window.open when responding to a user event, you should be fine using window.open — with all versions of IE.
There is no way to use location to open a new window. Just window.open or, of course, the user clicking a link with target="_blank".
If you go with the solution by #qiao, perhaps you would want to remove the appended child since the tab remains open and subsequent clicks would add more elements to the DOM.
// Code by #qiao
var a = document.createElement('a')
a.href = 'http://www.google.com'
a.target = '_blank'
document.body.appendChild(a)
a.click()
// Added code
document.body.removeChild(a)
Maybe someone could post a comment to his post, because I cannot.
You could try this:
<script type="text/javascript">
function newWindow(url){
window.open(url);
}
</script>
And call the function
If you are using an <a/> to trigger the report, you can try this approach. Instead of attempting to spawn a new window when window.open() fails, make the default scenario to open a new window via target (and prevent it if window.open() succeeds).
HTML
Link
JS
var spawn = function (e) {
try {
window.open(this.href, "","width=1002,height=700,location=0,menubar=0,scrollbars=1,status=1,resizable=0")
e.preventDefault(); // Or: return false;
} catch(e) {
// Allow the default event handler to take place
}
}
document.getElementById("myLink").onclick = spawn;
Why not have a hidden anchor tag on the page with the target set as you need, then simulate clicking it when you need the pop out?
How can I simulate a click to an anchor tag?
This would work in the cases where the window.open did not work
As of 2014, you can trigger the click on a <a/> tag. However, for security reasons, you have to do it in a click event handler, or the browser will tag it as a popup (some other events may allow you to safely trigger the opening).
jsFiddle
<input type="button" value="fake button" />

Categories