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

12

141

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?

Stanleystanly answered 20/12, 2013 at 3:59 Comment(0)
A
306

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;
});
Autolithography answered 8/9, 2016 at 9:39 Comment(11)
I using trying to use window.open in the success method for a jquery $.ajax call when async is set to true. Safari would ignore window.open. Changing jquery $.ajax call to async: false allowed window.open to work.Strapper
This identifies the problem, the cause of the problem, and a workaround. This should be the selected answer.Denys
Instead of window.open, window.open("about:blank","_blank") worked for meBusywork
how can this be used where does myService come from?Costotomy
@Costotomy myService is some async functionality is using to get the url to redirect.Galoot
Perfect solution works good in chrome, firefox and mac safari.Hominoid
In my case the url was a string and not of type location so i had to use windowReference.location.assign(url)Expound
Opening a new tab in Safari on iOS just works from an async function, just make sure you create the window (window.open) before calling the async callVariolous
This works in both desktop browsers and iOS Safari. Thanks for sharing.Life
It's worth noting that, if for whatever reason, you don't want the window to open when the promise resolves, you can call windowReference.close() to immediately close it.Vaseline
Does not work in Ionic for anyone looking for a that.Chelonian
V
62

Using setTimeout

EDIT: A few people are reporting that this method doesn't work anymore on the latest Safari.

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.

Vizard answered 23/12, 2021 at 15:9 Comment(13)
Cool workaround! Solved the issue on iPhone Safari for me. And thanks for the explanation.Semiology
UPDATE - target="_blank" stopped working for me. Had to use target="_top"Semiology
This answer is under valued! Thanks!Boucicault
This saved me after hours of mind-bending debugging. I have no idea how you'd even arrive at this solution without diving into the browser code. Thanks!!Catacomb
why is this required for window.open to work?Seating
@JoeBerg It's written in the answer above, Safari blocks all window.open requests if that request is made from an async call, using this method (setTimeout) we force the browser to run window.open on the main thread.Vizard
Can someone confirm this still works in latest Safari? I can't get it to work.Instruction
Doesn't work for me.Bhutan
Didn't work for me either...Firewood
Still doesn't work on iOS 16.6Shum
As on Oct 25, 2023. This worked for me.BUT I do not think this is the right long term approach. I guess some day dev's from Safari will stop this hack from working as well, cause this might cause security concers.Dagnydago
@Semiology suggestion target="_top" worked window.open(url, '_top');Halleyhalli
Its March 2024 and works for me! Thanks a lot!Retaliation
S
24

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>

Skittish answered 20/6, 2014 at 12:29 Comment(3)
The OP has a more complicated construction, so this answer might not be the solution for him. But for normal constructions this indeed does the trick. At least on iOS 11.3, Safari with default settings. If you put window.open in a function and call the function with onclick, Safari will not open a new tab. The function must be inside the to click element. A minor correction to the answer: <button onclick='window.open("https://www.google.com", "_blank");'>Open Google search</button>.Cheatham
@FrankConijn Thank you for your clarification and your correct. I have made the edit in my post to reflect your correction.Skittish
May i add : "Never use <a href="#" onclick="window.open(...);">" There is a subsection with THAT title on the window.open docs on developer.mozilla.org/en-US/docs/Web/API/Window/open. Seems pretty clear.Zepeda
C
22

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);
Chuck answered 30/7, 2020 at 10:12 Comment(4)
this also does not include the "_blank" (new tab)Appalling
@Dallas I guess you could add the attribute target in the process to have it behave as OP intended.Absolute
adding target attribute and setting it as _blank breaks this again, safari will block it as a pop-upDominquedominquez
This should be an accepted answer. Thanks.Piggy
M
16

window.location.assign(url) this fixs the window.open(url) issue in ios devices

Mikimikihisa answered 29/8, 2018 at 2:34 Comment(5)
This causes the url to be opened in the current tab, not in a new tab (as specified in the question).Weighty
Yup. This worked for me after fidgeting around a bit. I was trying to capture onScroll in an iPhone and it wasn't working though it was working on Safari in general. Thanks man.Subsolar
@JonSchneider It causes to open in the current tab because it is assigned to window. Besides that, assigning the url works better in the senario where your url is a String typeZepeda
Its working For ME. I don't need a popup window. Just need to open url. Thank you so much...Smokeproof
I wanna add a comment that this also works when you would like to download some images or documents from a certain url.Tomato
P
14

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:

  1. Safari -> Preferences
  2. Security -> Uncheck 'Block pop-up windows'
Philina answered 3/7, 2016 at 14:33 Comment(3)
but you cannot block customers' popup windowsBatson
@madd I think the point is that you need to go back to your designer and figure out how to solve the need without popping open a new window via JS or use a traditional href. The reason this answer is here is to alert people that browsers are making it more difficult to open popups.Philina
Downside: On IPads there does not seem to be a way to generally accept popups for a certain website so you have to confirm that you really want to open the popup every single time.Parasitic
S
7

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();
Shyster answered 20/5, 2021 at 6:26 Comment(2)
This trick doesn't work in safari ios.Undoubted
@liberborn, just checked on safari ios (iPhone) and it works. You need to add something like this: const onClickHandler = () => { const link = 'google.com'; const a = document.createElement("a"); a.setAttribute('href', link); a.setAttribute('target', '_blank'); a.click(); }Shyster
R
1

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.

Rangel answered 20/12, 2013 at 4:3 Comment(1)
I don't think this is it. Safari doesn't open the site anywhere. It's like I didn't execute the line.Stanleystanly
H
1

It will not work simply because safari has no support for that.

Check MDN Docs for compatibility - https://developer.mozilla.org/en-US/docs/Web/API/Window/open#browser_compatibility

Hairdresser answered 31/7, 2023 at 7:10 Comment(0)
G
0

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.

Georgeta answered 17/3, 2022 at 16:20 Comment(0)
N
0

That works like a charm in angular project

in HTML

<button #payBtn style="display: none" (click)="navigateToPay()"></button>

and in ts

@ViewChild('payBtn', { static: false, read: ElementRef }) payBtn: ElementRef;
pay_url: string = '';

after getting URL will use

this.pay_url = "your url";
     setTimeout(() => {
              this.payBtn.nativeElement.click();
       })


navigateToPay() {
    window.open(this.pay_url, "_blank");
  }
Nagel answered 21/4 at 23:52 Comment(0)
O
-14

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.

Oculomotor answered 26/9, 2014 at 22:52 Comment(1)
Incorrect, please, read the documentation first: developer.mozilla.org/en-US/docs/Web/API/Window/openTacho

© 2022 - 2024 — McMap. All rights reserved.