javascript 在用户单击 ajax 调用后打开没有弹出窗口阻止程序的新选项卡
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18885676/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Open new tab without popup blocker after ajax call on user click
提问by Syma
I have a page that enable user to perform image manipulation via HTML5 canvas, on the page, there's a facebook share button for sharing a generated image of the canvas on facebook.
我有一个页面,允许用户通过 HTML5 画布执行图像操作,页面上有一个 facebook 共享按钮,用于在 facebook 上共享画布的生成图像。
When the link is clicked, an ajax request is sent to the server (ASP.NET MVC) to perform the image generation, save the image on the server, then generate a url(that links to the image) that is returned as the ajax response. The returned url is what I want to pass as the parameter for facebook to share. The issue is that popup blocker is blocking facebook share dialog when I call "window.open".
当链接被点击时,一个ajax请求被发送到服务器(ASP.NET MVC)以执行图像生成,将图像保存在服务器上,然后生成一个url(链接到图像)作为ajax返回回复。返回的 url 是我想作为参数传递给 facebook 共享的。问题是当我调用“window.open”时,弹出窗口阻止程序阻止了 facebook 共享对话框。
Is there any other way to open a new tab without popup blocker. I believe that since the user initiated the action, there should be a way for me to bypass popup blocker. Thanks.
有没有其他方法可以在没有弹出窗口阻止程序的情况下打开新标签页。我相信既然用户发起了这个动作,我应该有办法绕过弹出窗口拦截器。谢谢。
回答by Christopher L?rken
Update Oct 2014:
2014 年 10 月更新:
It was noted correctly in the comments, that Firefox has deprecated the synchronous setting in June 2014, but it is still working in this browser.
评论中正确指出,Firefox 已于 2014 年 6 月弃用同步设置,但它仍在此浏览器中工作。
Furthermore, Chrome received updates which will only allow this to work as wanted if the ajax call returns in less than a second. Which is rather hard to gurantee. I've created another question devoted to the Chrome timeout: Synchronous Ajax - does Chrome have a timeout on trusted events?
此外,Chrome 收到了更新,如果 ajax 调用在不到一秒的时间内返回,它只会允许它按需要工作。这很难保证。我创建了另一个专门针对 Chrome 超时的问题: 同步 Ajax - Chrome 是否对受信任的事件有超时?
The linked post contains a JSFiddle demonstrating this concept and the problem.
链接的帖子包含一个 JSFiddle,展示了这个概念和问题。
Original Answer
原答案
Short answer: Make the ajax request synchronous.
简短回答:使 ajax 请求同步。
Full answer: A browser will only open a tab/popup without the popup blocker warning, if the command to open the tab/popup comes from a trusted event. That means: The user has to actively click somewhere to open a popup.
完整答案:如果打开选项卡/弹出窗口的命令来自受信任的事件,浏览器将只打开一个没有弹出窗口阻止程序警告的选项卡/弹出窗口。这意味着:用户必须主动点击某处才能打开弹出窗口。
In your case, the user performs a click so you have the trusted event. You do loose that trusted context however, by performing the Ajax request. Your success handler does not have that event any more. The only way to circumvent this is to perform a synchronous Ajax request which will block your browser while it runs, but will preserve the event context.
在您的情况下,用户执行单击操作,以便您获得受信任的事件。但是,通过执行 Ajax 请求,您确实失去了可信上下文。您的成功处理程序不再有该事件。避免这种情况的唯一方法是执行同步 Ajax 请求,该请求将在浏览器运行时阻塞浏览器,但会保留事件上下文。
In jQuery this should do the trick:
在 jQuery 中,这应该可以解决问题:
$.ajax({
url: 'http://yourserver/',
data: 'your image',
success: function(){window.open(someUrl);},
async: false
});
回答by wsgeorge
Here's how I got round the issue of my async ajax request losing the trusted context:
以下是我如何解决异步 ajax 请求丢失可信上下文的问题:
I opened the popup directly on the users click, directed the url to about:blank
and got a handle on that window. You could probably direct the popup to a 'loading' url while your ajax request is made
我直接在用户点击时打开了弹出窗口,将 url 定向到about:blank
并获得了该窗口的句柄。您可以在发出 ajax 请求时将弹出窗口定向到“正在加载”网址
var myWindow = window.open("about:blank",'name','height=500,width=550');
Then, when my request is successful, I open my callback url in the window
然后,当我的请求成功时,我在窗口中打开我的回调 url
function showWindow(win, url) {
win.open(url,'name','height=500,width=550');
}
回答by Chris Broski
The answer from wsgeorgeis the one that got me on the right track. Here is a function that hopefully illustrates the technique more clearly.
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);
}