我有一个页面,允许用户通过HTML5画布执行图像处理,在页面上,有一个Facebook分享按钮,用于在Facebook上共享生成的画布图像。
单击链接时,会向服务器(ASP.NET MVC)发送ajax请求以执行图像生成,将图像保存在服务器上,然后生成返回的URL(链接到图像)作为ajax的回应。返回的url是我想要传递的Facebook要分享的参数。问题是,当我调用“window.open”时,弹出窗口阻止程序阻止了facebook共享对话框。
有没有其他方法可以在没有弹出窗口拦截器的情况下打开新标签页。我相信,既然用户发起了动作,我应该有办法绕过弹出窗口拦截器。感谢。
答案 0 :(得分:59)
评论中正确指出,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);
}