点击事件期间窗口打开弹出被阻止

31

我的最终目的是运行一个$.ajax()调用,然后在其运行后打开一个新窗口。

用户点击“预览”按钮,保存他们当前的表单,然后打开一个显示刚刚保存数据的项目预览的新窗口。

但是,window.open函数会被弹出拦截器阻止。

以下是我的代码的基本部分:

HTML:

<a href="/surveys/185/preview" class="preview" target="_blank">Preview</a>

JavaScript:

$('.preview').live('click', function(event){
  save_survey($(this).attr('href'));
  event.preventDefault();
});

function save_survey(url) {
  $.ajax({
    type: "POST",
    url: form_url,
    dataType: 'json',
    data: form_data,
    success: function(data) {
      window.open(url, '_blank');
    }
  });
}
5个回答

84

最近我遇到了这个问题,找到了以下解决方法:

1)在调用$.ajax之前调用window.open并保存窗口引用:

var newWindow = window.open(...);

2)在回调函数上设置已保存窗口引用的location属性:

newWindow.location = url;

或许它也能帮助你。


5
太聪明了!我原本以为没有希望了。 - JayD3e
实际上,这似乎不再起作用了。有人能确认这是不可能的吗? - JayD3e
@IgorDymov 这似乎在主流浏览器中可行。您能否详细解释一下为什么会这样? - Abhishek
2
谢谢,你是我的英雄,爱你。 - Nam Nguyen
对于那些发现这不起作用的人,我注意到如果没有由用户触发的事件引发,window.open可能会返回null:https://dev59.com/questions/DWMl5IYBdhLWcg3wcmrD#18401663。 - woz
如果在 Ajax 响应之前我没有 URL 怎么办? - Muhammed Moussa

15

弹出窗口拦截器通常会阻止显示非由直接用户操作触发的任何弹出窗口,例如点击按钮或链接。

如果您在单击事件上使用ajax请求,则该请求将异步从单击事件触发,这就是为什么当ajax请求完成其工作并获得带有响应的事件时,您已经失去了在没有弹出窗口拦截器干扰的情况下触发window.open的机会,原始的单击事件早已结束。


3
根据这篇文章,看起来你需要在点击时直接打开窗口(以避免被弹出拦截器阻止),而不是等待AJAX调用完成后再打开新窗口。

1

我通过将Ajax调用设置为同步来解决了我的问题。例如(使用jQuery):

$("form").submit(function(e){
    e.preventDefault();
    $.ajax({
      async: false,
      url: ...,
      data: ...,
      success: function(results){
          if(results.valid){
              window.open(...);
          }
      }
    });
    return false;
  });

0
const newWin = window.open(`${BASE_URL}`, 'expampleName')
if (newWin) {
  newWin.onload = () => {
    const currentOpenWindow = newWin
    const href = newWin.location.href
  }
}

3
请问,您能否解释一下这个回答是如何回答问题的? - Homungus
如果您提供为什么这是首选解决方案的解释并解释其工作原理,那将更有帮助。我们想要教育,而不仅仅提供代码。 - the Tin Man

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接