在用户单击ajax调用后打开没有弹出窗口阻止程序的新选项卡

时间:2013-09-19 03:21:29

标签: javascript popupwindow popup-blocker

我有一个页面,允许用户通过HTML5画布执行图像处理,在页面上,有一个Facebook分享按钮,用于在Facebook上共享生成的画布图像。

单击链接时,会向服务器(ASP.NET MVC)发送ajax请求以执行图像生成,将图像保存在服务器上,然后生成返回的URL(链接到图像)作为ajax的回应。返回的url是我想要传递的Facebook要分享的参数。问题是,当我调用“window.open”时,弹出窗口阻止程序阻止了facebook共享对话框。

有没有其他方法可以在没有弹出窗口拦截器的情况下打开新标签页。我相信,既然用户发起了动作,我应该有办法绕过弹出窗口拦截器。感谢。

3 个答案:

答案 0 :(得分:59)

2014年10月更新:

评论中正确指出,Firefox已于2014年6月弃用了同步设置,但它仍在此浏览器中运行。

此外,如果ajax调用在不到一秒的时间内返回,则Chrome会收到更新,这些更新只会允许其按预期工作。这是很难保证的。我创建了另一个专门针对Chrome超时的问题: Synchronous Ajax - does Chrome have a timeout on trusted events?

链接的帖子包含一个JSFiddle,展示了这个概念和问题。

原始答案

简短回答:使ajax请求同步。

完整答案: 如果打开选项卡/弹出窗口的命令来自trusted event,则浏览器只会在没有弹出窗口阻止程序警告的情况下打开选项卡/弹出窗口。这意味着:用户必须主动点击某处才能打开弹出窗口。

在您的情况下,用户执行单击以便您拥有受信任的事件。但是,通过执行Ajax请求,您确实失去了可信上下文。您的成功处理程序不再具有该事件。 避免这种情况的唯一方法是执行同步Ajax请求,该请求会在浏览器运行时阻止它,但会保留事件上下文。

在jQuery中,这应该可以解决问题:

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

答案 1 :(得分:23)

以下是我如何解决我的异步ajax请求丢失可信上下文的问题:

我直接在用户点击上打开了弹出窗口,将网址指向about:blank并在该窗口上获得了一个句柄。您可以在创建ajax请求时将弹出窗口指向“加载”URL

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

然后,当我的请求成功时,我在窗口中打开我的回调网址

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

答案 2 :(得分:6)

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);
}