iOS13にしたら、同期処理のAjax後のwindow.openができなくなった

今まで、Ajax後にwindow.openで新規ページを開きたい場合、同期処理でAjaxを呼ぶようにすると(それをAjaxといっていいか微妙ですが…)、ポップアップブロックをオンにしていてもページを開くことができました(参考:Ajaxでポップアップブロックを回避する方法 – LAZE SOFTWARE)。例えば下記のような処理です。

    var xhr = new XMLHttpRequest();
    // ハンドラの登録.
    xhr.onreadystatechange = function () {
        switch (xhr.readyState) {
            case 4: // データ受信完了.
                window.open('https://www.yahoo.co.jp/', '_blank');
                break;
        }
    };
    var apiUrl = 'test.json';
    xhr.open('GET', apiUrl, false); // 同期通信(ポップアップエラーをださないため)
    try{
        xhr.send();
    } catch (e) {
        alert('APIの呼び出しに失敗しました');
    }

Ajaxの書き方が古いとか言われそうですが、xhr.openの第3引数でfalseを指定すると、非同期ではなく、同期処理になります。こうすることで、ポップアップブロックしていても今までなら

ですが、iOS端末でiOS13(もしくはiPadOS13)にアップデートすると、同期処理のAjaxでもwindow.openが機能しなくなってしまいました(泣)。

ちなみに、window.openの返り値はwindowオブジェクトではなく、nullになります。nullならポップアップを許可してくださいとメッセージをだすことができそうです。

なお、もう一つの対策として、Ajaxを呼ぶ前に空のページでwindow.openを呼んでおくという方法があるようです。
参考:クリックイベントの中で非同期処理したあとに別ウィンドウで開くときにポップアップブロックにひっかからない方法 – Webtech Walker

    var xhr = new XMLHttpRequest();
    var w = window.open('', '_blank'); // 先に空のページを開いて
    // ハンドラの登録.
    xhr.onreadystatechange = function () {
        switch (xhr.readyState) {
            case 4: // データ受信完了.
                w.location.href = 'https://www.yahoo.co.jp'; // URLを変更する
                break;
        }
    };
    var apiUrl = 'test.json';
    xhr.open('GET', apiUrl, false); // 同期通信(ポップアップエラーをださないため)
    try{
        xhr.send();
    } catch (e) {
        alert('APIの呼び出しに失敗しました');
    }

これでうまくいけそうですね。一つ欠点としては、Ajaxで判断してエラーなどがあった場合も新しいウィンドウが開いてしまいますが、その場合は、「w.close()」で閉じればいいだけです。

コメント

タイトルとURLをコピーしました