Chrome window.open после запроса ajax действует как всплывающее окно
У меня есть ситуация, когда пользователь нажимает кнопку, я выполняю запрос ajax, а затем использую результат запроса ajax для создания URL-адреса, который я хочу открыть на новой вкладке. Тем не менее, в chrome, когда я вызываю window.open в обработчике успеха для запроса ajax, он открывается в новом окне, как всплывающее окно (и блокируется всплывающими блоками). Я предполагаю, что, поскольку код успеха асинхронен из кода обработки кликов, который хром считает, что он не был вызван щелчком, хотя он причинно связан с щелчком. Есть ли способ предотвратить это, не делая синхронный запрос ajax?
EDIT Вот несколько минимальных кодов, которые демонстрируют это поведение:
$('#myButton').click(function() {
$.ajax({
type: 'POST',
url: '/echo/json/',
data: {'json': JSON.stringify({
url:'http://google.com'})},
success: function(data) {
window.open(data.url,'_blank');
}
});
});
http://jsfiddle.net/ESMUA/2/
Одна нота пояснений: меня больше беспокоит ее открытие в отдельном окне, а не в виде вкладки, чем я о том, что он блокируется блокировщиком всплывающих окон.
Ответы
Ответ 1
Попробуйте добавить
window.open(url,'_blank');
редактировать
Ну, я не думаю, что вы можете обойти всплывающие блокираторы при открытии страницы, которая не является непосредственным результатом действия пользователя (т.е. Не async).
Вы могли бы попробовать что-то вроде этого, но оно должно выглядеть как действие пользователя для всплывающего блока:
var $a = $('<a>', {
href: url,
target: '_blank'
});
$(document.body).append($a);
$a.click();
Изменить 2
Похоже, вам лучше синхронизировать ситуацию.
Пока новое окно является "одним и тем же источником", у вас есть возможность манипулировать им с помощью JS.
$('#a').on('click', function(e){
e.preventDefault();
var wi = window.open('about:blank', '_blank');
setTimeout(function(){ // async
wi.location.href = 'http://google.com';
}, 500);
});
Ответ 2
Попробуйте добавить async: false. Он должен работать
$('#myButton').click(function() {
$.ajax({
type: 'POST',
async: false,
url: '/echo/json/',
data: {'json': JSON.stringify({
url:'http://google.com'})},
success: function(data) {
window.open(data.url,'_blank');
}
});
});
Ответ 3
Ответ, отправленный на @pstenstrm выше (Edit 2), в основном работает, но я добавил только одну строку, чтобы сделать решение более элегантным. В моем случае вызов ajax занял больше секунды, и пользователь, столкнувшийся с пустой страницей, столкнулся с проблемой. Хорошо, что есть способ разместить содержимое HTML в новом окне, которое мы только что создали.
например:
$('#a').on('click', function(e){
e.preventDefault();
var wi = window.open('about:blank', '_blank');
$(wi.document.body).html("<p>Please wait while you are being redirected...</p>");
setTimeout(function(){ // async
wi.location.href = 'http://google.com';
}, 500);
});
Это заполняет новую вкладку текстом "Подождите, пока вы перенаправляетесь...", который кажется более элегантным, чем пользователь, который смотрит на пустую страницу на секунду. Я хотел опубликовать это как комментарий, но не имею достаточной репутации.
Ответ 4
Что для меня работало:
var win = window.open('about:blank', '_blank');
myrepository.postmethod('myserviceurl', myArgs)
.then(function(result) {
win.location.href = 'http://yourtargetlocation.com/dir/page';
});
Вы открываете вкладку нового окна перед вызовом синхронизации, пока вы все еще в области видимости, захватываете дескриптор окна, а затем повторно перемещаетесь после получения результатов ajax в обещании.
Ответ 5
Нет надежного способа. Если ваша вкладка/окно заблокирована поп-блокером в FF и IE6 SP2, тогда window.open вернет значение null.
https://developer.mozilla.org/en-US/docs/Web/API/Window/open#FAQ
Как я могу узнать, когда окно заблокировано блокировщиком всплывающих окон? С помощью встроенных блокировщиков всплывающих окон Mozilla/Firefox и Internet Explorer 6 SP2 вы должны проверить возвращаемое значение window.open(): оно будет null, если окно не было разрешено открывать. Однако для большинства других блокировщиков всплывающих окон нет надежного способа.