TIL / web development

Safari blocking new window opened from clicking button in web application

I work on a web application that includes a feature that integrates with another of my company’s products. You trigger the integration by clicking a button in the first web app, which launches the second web app and passes along a document. The code is a little something like this:

$(document).on('click', '.my-button', function(e) {
  $.ajax({
     method: 'POST',
     url: '/api/call/to/get/the/url/we/need/to/open',
       error: function (status, err) { },
       success: function (data) {
         window.open(data.redirectUrl);
        }
     });
});

I mostly use Chrome on either a Mac or Linux laptop and this has worked fine. But yesterday I got a report that the button was not functioning on Safari. Turns out that the window.open was being blocked by Safari’s popup blocker. Of course, the easiest thing is to just tell the user to turn off their popup blocker. But that’s obviously not ideal.

So I did some digging and found other people had run into similar issues with Safari. But the solution is relatively simple, according to this StackOverflow link. Do the window.open first, with no target, and then set that window’s location.

However, this still didn’t fix the issue for me. Digging a little deeper into the comments on the post, one additional thing I discovered is that the ajax call that’s triggering this also needs to _NOT_ be asynchronous. Well, this is not ideal, but the web app is basically blocked until this completes anyway, so this turns out to be a good enough solution for now. The API call is pretty fast, but I throw up a little temporary modal with a spinner while this is being processed so the window doesn’t just completely freeze up with no feedback.

So the fixed code looks a little like this

$(document).on('click', '.my-button', function(e) {
  $.ajax({
     method: 'POST',
     async: false,
     url: '/api/call/to/get/the/url/we/need/to/open',
       error: function (status, err) { },
       success: function (data) {
         var newWindow = window.open();
         newWindow.location = data.redirectUrl;
        }
     });
});

Hope this helps someone! And of course I welcome any feedback on better ways of handling this.

Leave a Reply

Your email address will not be published. Required fields are marked *