Open new tab without popup blocker after ajax call on user click

Syma picture Syma · Sep 19, 2013 · Viewed 66.7k times · Source

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.

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".

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.

Answer

Christopher Lörken picture Christopher Lörken · Oct 9, 2013

Update Oct 2014:

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.

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?

The linked post contains a JSFiddle demonstrating this concept and the problem.

Original Answer

Short answer: Make the ajax request synchronous.

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.

In jQuery this should do the trick:

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