41

我有一个页面,使用户能够通过 HTML5 画布执行图像处理,在页面上,有一个 facebook 共享按钮,用于在 facebook 上共享生成的画布图像。

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

有没有其他方法可以在没有弹出窗口阻止程序的情况下打开新标签。我相信既然用户发起了这个动作,我应该有办法绕过弹出窗口阻止程序。谢谢。

4

3 回答 3

59

2014 年 10 月更新:

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

此外,Chrome 收到了更新,只有在 ajax 调用在不到一秒的时间内返回时才允许它按需要工作。这很难保证。我创建了另一个专门针对 Chrome 超时的问题: Synchronous Ajax - Chrome 是否对可信事件有超时?

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

原始答案

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

完整答案:如果打开选项卡/弹出窗口的命令来自受信任的事件,浏览器只会打开没有弹出窗口阻止程序警告的选项卡/弹出窗口。这意味着:用户必须主动单击某处才能打开弹出窗口。

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

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

$.ajax({
 url: 'http://yourserver/',
 data: 'your image',
 success: function(){window.open(someUrl);},
 async: false
});
于 2013-10-09T18:05:54.883 回答
24

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

我直接在用户单击时打开了弹出窗口,将 url 定向到about:blank并在该窗口上获得了句柄。在发出 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');
}
于 2015-10-19T13:50:45.190 回答
8

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);
}
于 2016-09-19T20:14:29.920 回答