Откройте новую вкладку без блокировщика всплывающих окон после вызова ajax при нажатии пользователем

У меня есть страница, которая позволяет пользователю выполнять манипуляции с изображениями через холст HTML5, на странице есть кнопка общего доступа к facebook для совместного использования сгенерированного изображения холста на facebook.

При щелчке ссылки на сервер (ASP.NET MVC) отправляется запрос ajax для выполнения генерации изображения, сохранения изображения на сервере, затем создается URL-адрес (который ссылается на изображение), который возвращается как ответ ajax. Возвращенный url - это то, что я хочу передать как параметр для обмена facebook. Проблема в том, что блокиратор всплывающих окон блокирует диалог общего доступа к facebook, когда я вызываю "window.open".

Есть ли другой способ открыть новую вкладку без блокировщика всплывающих окон. Я считаю, что, поскольку пользователь инициировал действие, должен быть способ обойти блокировщик всплывающих окон. Спасибо.

Ответ 1

Обновление октябрь 2014:

В комментариях было правильно отмечено, что Firefox устарел в синхронном режиме в июне 2014 года, но он все еще работает в этом браузере.

Кроме того, Chrome получил обновления, которые позволят ему работать так, как требуется, если вызов ajax вернется менее чем за секунду. Что довольно сложно гарантировать. Я создал еще один вопрос, посвященный тайм-ауту Chrome: синхронный Ajax - есть ли у Chrome таймаут для доверенных событий?

Связанный пост содержит JSFiddle, демонстрирующий эту концепцию и проблему.

Оригинальный ответ

Краткий ответ: сделайте запрос ajax синхронным.

Полный ответ: браузер будет открывать вкладку/всплывающее окно без предупреждения блокировщика всплывающих окон, если команда для открытия вкладки/всплывающего окна поступает из доверенного события. Это означает: пользователь должен активно щелкнуть где-нибудь, чтобы открыть всплывающее окно.

В вашем случае пользователь выполняет щелчок, чтобы вы получили доверенное событие. Однако вы теряете этот доверенный контекст, выполняя запрос Ajax. Ваш обработчик успеха больше не имеет этого события. Единственный способ обойти это - выполнить синхронный Ajax-запрос, который заблокирует ваш браузер во время работы, но сохранит контекст события.

В jQuery это должно сработать:

$.ajax({
 url: 'http://yourserver/',
 data: 'your image',
 success: function(){window.open(someUrl);},
 async: false
});

Ответ 2

Вот как я обошел проблему моего асинхронного запроса async, потерявшего доверенный контекст:

Я открыл всплывающее окно непосредственно на клике пользователей, направил url на about:blank и получил ручку в этом окне. Вероятно, вы можете направить всплывающее окно на URL-адрес загрузки, пока ваш запрос ajax будет сделан

var myWindow = window.open("about:blank",'name','height=500,width=550');

Затем, когда мой запрос будет успешным, я открою URL-адрес обратного вызова в окне

function showWindow(win, url) {
    win.open(url,'name','height=500,width=550');
}

Ответ 3

Ответ от wsgeorge - это тот, который дал мне правильный путь. Вот функция, которая, надеюсь, более четко иллюстрирует технику.

function openNewAjaxTab(url) {
    var tabOpen = window.open("about:blank", 'newtab'),
        xhr = new XMLHttpRequest();

    xhr.open("GET", '/get_url?url=' + encodeURIComponent(url), true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            tabOpen.location = xhr.responseText;
        }
    }
    xhr.send(null);
}