2

I have a webpage that opens a pop-up window using window.open with some request parameter. The parameter is obtained from ajax call and window.open is called right inside of xhr's handler

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (this.readyState == 4) {
        switch (this.status) {
            case 200:
                window.open("script.php?param2="+this.responseText, "_blank", "...");
                break;
            default:
                alert('aw snap');
                break;
            }
        }
    };
xhr.open("GET", "first_script.php?param1=3", false);
xhr.send();

As you can see this ajax call is made synchronous, which is generating warning in a browser's console. If a make this ajax call asynchronous, the warning won't appear, but the pop-up window will be blocked by browser, because it wasn't called directly by user.

I basically need to obtain some data with ajax call, wait for it, and then call window.open with obtained data as a request parameter.

I've seen the solutions on how to wait for async requests here: How do I return the response from an asynchronous call?

But, the discussion in that topic is advising to abstain from synchronous calls at all, because it's considered a bad practice.

I'm really confused. Can you please give me a hint, how to achieve this behavior, the right way? The behavior that I am trying to achieve is quite common, I think. There must be a normal way of doing this without re-inventing the wheel.

JackHammer
  • 458
  • 1
  • 3
  • 16

1 Answers1

1

You should avoid using synchronous XHR because it's deprecated in modern browsers.

Popup blockers usually works blocking every popup shown not triggered by a direct user action, like clicking on a button or a link.

The solution to your problem, is to create and store a new window before sending the asynchronous XHR, and change it's location when you get the response:

    var newWindow = window.open("", "_blank");
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (this.readyState == 4) {
            switch (this.status) {
                case 200:
                    newWindow.location = "script.php?param2="+this.responseText;
                    break;
                default:
                    alert('aw snap');
                    break;
            }
        }
    };
    xhr.open("GET", "first_script.php?param1=3", true);
    xhr.send();
Below the Radar
  • 7,321
  • 11
  • 63
  • 142