13

Google Chrome seems to be blocking a popup I am creating via jQuery. After some investigation, it appears to be an issue with calling window.open in the success event of an ajax call. Is there a way around this? My jQuery ajax call returns the URL to be opened. So I am bit stuck.

It works if I place the window.open outside the ajax call; but, inside (i.e. in the success event) it is blocked. I think it is something to do with CONTEXT but I am unsure.

Here is what I have:

     window.open("https://www.myurl.com");  // OUTSIDE OF AJAX - no problems 
                                            // with popup

     $.ajax({
        type: "POST",
        url: "MyService.aspx/ConstructUrl",
        data: jsonData,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) {
            // Normally loads msg.d which is the url returned from service
            // static url below is for testing
            window.open("https://www.myurl.com");  // THIS IS BLOCKED
        },
        error: function(msg) {
            // alert(error);
        }
    });
Lee
  • 922
  • 2
  • 11
  • 19
mark smith
  • 20,637
  • 47
  • 135
  • 187

9 Answers9

18

As several people have pointed out, the accepted answer no longer works. Based on the comment by aidiakapi, I used a workaround by first opening the window.

window.open("about:blank", "myNewPage");

Then doing the ajax business and in the done() function, open the page with that name.

window.open("/foo.html", "myNewPage");

This also doesn't matter if you do it async or not.

Andrew
  • 1,571
  • 17
  • 31
  • This works for me in the latest versions of Safari, Chrome and Firefox. It should be the accepted answer. – wbyoung Oct 24 '13 at 13:11
  • [Another way that seems to work well.](http://stackoverflow.com/a/16361814/98069) – wbyoung Oct 24 '13 at 13:21
  • This won't work if you need to open a new window conditionally on what you get back in the data. In our case we should only open a new tab if we find a certain value in our JSON object that we get back. With this approach, we would be opening/closing windows. – gene b. Aug 05 '14 at 16:08
  • 1
    @geneb. The answer for you is simple: you can't. If you open a window without a user action, it will be blocked by the browser. This workaround works because it opens the window on the user action. You need to add a user action. So the best you can do is wait for your JSON, then display a "ready" button for the user to click. – Andrew Aug 07 '14 at 21:19
  • Working great! Life saving answer. :) – Ajay Makwana Dec 08 '17 at 05:31
9

Simply open the new window in the success callback:

 $.ajax({
    type: "POST",
    url: "MyService.aspx/ConstructUrl",
    data: jsonData,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(msg) {
        window.open("https://www.myurl.com"); 
    },
    error: function(msg) {
        //alert(error);
    }
});

Note you might have to set $.ajax's async option to false for that, otherwise the code following the $.ajax call could be evaluated before the response is received.

kritzikratzi
  • 19,662
  • 1
  • 29
  • 40
karim79
  • 339,989
  • 67
  • 413
  • 406
  • karim, you just saved my day! – jodeci Jun 21 '10 at 07:57
  • 4
    What's the use of AJAX (which after all means 'Asynchronous Javascript And Xml') when you're not using it asynchronous? There are several alternatives, like using a modal, opening the window before the request, showing a load text, and redirecting the window on completion. I think this is quite dirty. – Aidiakapi Mar 01 '12 at 08:55
  • @pst - Good lord. I was young back then. I will fix this. – karim79 Jul 12 '12 at 10:40
  • You're welcome .. I'm just saved that nobody reads my old answers ^^ –  Jul 12 '12 at 18:20
  • 13
    @karim79 I think now the code in the question and in your answer are identical. I have the same problem and can't get it to work properly too: if window.open is used in the "success" callback, it gets blocked by browsers. – parrker9 Jul 14 '12 at 06:19
  • 1
    @parrker9 if you look at the edit history you can see that there was a note about the async flag being set to false. in it's current state the answer is useless, imho – kritzikratzi Oct 16 '13 at 03:39
  • $.ajax({ async: false, type: "POST", – Amir Hosseinzadeh Jan 29 '19 at 16:45
7

Your code returns these in firefox and chrome:

Firefox: "Firefox prevented this site from opening a pop-up window." Chrome: "Pop-up blocked"

To fix this issue just add async:false to your ajax call.

$.ajax({
type: "POST",
async: false,
url: "MyService.aspx/ConstructUrl",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(url) {
    window.open(url); 
},
error: function(msg) {
    //alert(error);
}

});

Just be careful that async:false will force javascript to wait for jQuery ajax result. It means it freezes javascript until ajax call is completed.

Code.Town
  • 1,216
  • 10
  • 16
2

Firefox does popup blocking based on the event that causes the javascript code to run; e.g., it will allow a popup to open that was triggered from an onclick, but not one that was triggered by a setTimeout. It has gotten a little bit complicated over the years as advertisers have tried to circumvent firefox's popup blocker.

Matt Bridges
  • 48,277
  • 7
  • 47
  • 61
1

Follow the method described in this post:

window.open without popup blocker using AJAX and manipulating the window.location

In a nutshell, the approach is:

  1. Your code must be initiated by an onclick event.
  2. Open a new window, perhaps initially with no content, with window.open --- and store a reference to the window so that you can use it later.
  3. In the success callback from your AJAX operation, use window.location.replace to manipulate the URL of your already-open window with the desired URL.
Community
  • 1
  • 1
zachelrath
  • 842
  • 5
  • 11
1
 if you put async:true then you must do the following:

 var safariOP = window.open("https://www.myurl.com");  // DEFINE BEFORE AJAX CALLBACK 

 $.ajax({
    type: "POST",
    url: "MyService.aspx/ConstructUrl",
    data: jsonData,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(msg) {
      if(safariOP){
         safariOP.focus(); // IT'S OK ON SAFARI
      }
    },
    error: function(msg) {
        //alert(error);
    }
});
tiepnv
  • 336
  • 2
  • 9
1

You can still have the code in the success event but async will need to be false.

Craig
  • 2,093
  • 3
  • 28
  • 43
0

if you put async:true then you must do the following:

var safariOp = window.open("https://www.myurl.com"); //define before callback ajax contains url .
 $.ajax({
    type: "POST",
    url: "MyService.aspx/ConstructUrl",
    data: jsonData,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(msg) {
        //it's ok on safari
        safariOp.focus();
    },
    error: function(msg) {
        //alert(error);
    }
});
manikant gautam
  • 3,521
  • 1
  • 17
  • 27
tiepnv
  • 336
  • 2
  • 9
0

this works for me.

$(document).ready(function() {
        $('#myLink').on( "click", function() {
            var myNewTab = window.open('about:blank', '_blank');
            $.ajax({
                method: "POST",
                url: "ajax.php",
                data: { name: "John", location: "Boston" },
            })
            .done(function( msg ) {
                myNewTab.location.href = "google.com";
            });
        });
    });
Rameshwor Maharjan
  • 242
  • 2
  • 3
  • 10