在不受弹窗阻拦的情况下打开新窗口

54

希望您能在这里给点帮助... 我有一个表单,它可以将字段中的单词翻译,填充翻译后的术语并在单个提交按钮中执行所有操作。

提交是由jquery完成的。 问题是,目标页面被阻止了,因为所有三个主要的浏览器都将其视为弹出窗口, 您知道如何让它只作为新标签页或新窗口打开吗? 我不想将目标设置为_self,因为我希望人们也能打开我的网站。

我认为问题出在这个字符串中:

document.forms.form1.submit();

但我知道应该有一种方法来重新表达它,使得目标不会被视为弹出窗口。

这是脚本:

<script type="text/javascript">

$(function transle() {
  $('#transbox').sundayMorningReset();
  $('#transbox input[type=button]').click(function(evt) {
    $.sundayMorning(
      $('#transbox input[type=text]').val(), {
        source: '',
        destination: 'ZH',
        menuLeft: evt.pageX,
        menuTop: evt.pageY
      },
      function(response) {
        $('#transbox input[type=text]').val(response.translation);

        //document.getElementById("form1").submit();
        document.forms.form1.submit();

      }
    );
  });
});

</script>

这是表单:

<table id="transbox" name="transbox" width="30px" border="0" cellspacing="0" cellpadding="0">
  <form action="custom-page" method="get" name="form1" target="_blank" id="form1">

    <tr>
      <td>
        <input id="q" name="q" type="text" class="search_input" onFocus="if (this.value == 'Evening dress') {this.value = '';}" onBlur="if (this.value == '') {this.value = 'Evening dress';}" value="Evening dress" />
      </td>
      <td>
        <input type="button" value="Find" style="color: #333; width: 157px; font-weight:bold"></input>
      </td>
    </tr>

  </form>
</table>

编辑

我尝试了所有这些字符串进行提交:

document.getElementById("form1").submit();
document.forms.form1.submit();
form1.submit();

最后都会以目标被弹出窗口拦截结束。 请问还有其他方法可以让代码不弹出窗口吗?

也许应该使用onsubmit来制作jQuery? 有人知道怎么做吗?


它在弹出窗口拦截器关闭时是否有效。此外,您可以使用$("#form1").submit();提交表单,而不是document.forms.form1.submit();。 - Adam Magaluk
尝试在提交按钮上调用 $("button").click()。 - Adam Magaluk
and $("#form1").submit(); 没有任何作用... - li.
请查看以下链接:https://dev59.com/5XVC5IYBdhLWcg3wz0h9 - Adam Magaluk
浏览器开始实现弹出窗口拦截器是有原因的。与其与之斗争,不如重新考虑是否需要弹出窗口。 - DA.
显示剩余3条评论
7个回答

92

只有当打开标签/弹出窗口的命令来自于可信事件时,浏览器才会在没有弹出拦截警告的情况下打开标签/弹出窗口。这意味着用户必须主动点击某个地方才能打开弹出窗口。

在您的情况下,用户执行了点击操作,因此您具有可信事件。然而,通过执行Ajax请求,您失去了该可信上下文。您的成功处理程序不再具有该事件。唯一的绕过方式是执行同步的Ajax请求,这将在运行时阻止您的浏览器,但将保留事件上下文。

在jQuery中,可以使用以下方法解决:

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

这里是你的答案:如何在用户点击后通过AJAX调用打开新标签页而不被弹出拦截


5
这个解决方案似乎不再起作用了。新窗口没有打开,Web控制台显示错误:“由于对最终用户体验的负面影响,主线程上的同步XMLHttpRequest已被弃用。获取更多帮助,请访问http://xhr.spec.whatwg.org/。” - John Smith Optional
这个解决方案在我的浏览器上运行,并显示上述警告。 - Guillaume Massé
代码可以运行,但我收到了警告:[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. 有关更多帮助,请查看 https://xhr.spec.whatwg.org/。 - hoogw
1
async:false 对我来说是解决方案,谢谢。 - sradha

23

在所有浏览器中,这是唯一一个对我有效的方法。

let newTab = window.open(); newTab.location.href = url;


对我有用。谢谢! - Duc Manh Nguyen

13
作为一般规则,弹出窗口拦截器会针对没有用户交互而启动的窗口进行拦截。通常,除非是非常差的弹出窗口拦截器,否则点击事件可以打开窗口而不会被拦截。
请尝试在点击事件后启动窗口。

7

PS> 我在一个相关问题上发布了这个答案。这是我如何解决异步ajax请求失去受信任上下文问题的方法:

我直接在用户点击时打开弹出窗口,将URL定向到about:blank并获取该窗口的句柄。您可能可以在进行ajax请求时将弹出窗口重定向到“loading” URL。

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

然后,在我的请求成功时,在窗口中打开我的回调URL。

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

2
这适用于无论你想打开一个新窗口的情况。如果开放基于回调函数的条件,我们将不得不调用.close(),这将创建一个打开/关闭的闪烁... 有什么想法吗? - LeOn - Han Li

4

为了添加提交按钮,请加入以下代码,然后设置你的表单 target="newwin"。

onclick=window.open("about:blank","newwin") 

0
我的情况稍微复杂一些,因为我的初始用户交互是通过点击按钮来触发一个事件处理程序,该事件处理程序调用了一个方法,该方法返回一个承诺(promise),其中包含一个ajax调用,而当这个承诺被实现时,实际上应该打开URL。
我唯一能够使其正常工作的方法是按照这里建议的两个步骤进行操作。
function someFunctionThatsCalledByUserClick(){
    return new Promise((resolve, reject)=>{
        let newTab = window.open();     // <-- always open new tab
        return ajax_wrapper_func().then( data => {
            let url = extract_url(data);
            newTab.location.href = url;     // <-- set the url
            resolve();
        }).catch(e=>{
            newTab.close();     // <-- remove the tab on errors
            reject(e);
        });
    });
}

-2
function openLinkNewTab (url){
    $('body').append('<a id="openLinkNewTab" href="' + url + '" target="_blank"><span></span></a>').find('#openLinkNewTab span').click().remove();
}

3
为了帮助OP解决当前的问题,请在回答中加入一些解释,说明这个答案如何有助于解决问题。 - ρяσѕρєя K
1
在Scratchpad(Firefox)中快速尝试了一下,正如预期的那样,这触发了我的弹出窗口拦截器。 openLinkNewTab('https://ddg.gg'); - retrovertigo

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