避免浏览器弹出窗口拦截器

发布于 2024-08-27 12:04:16 字数 174 浏览 4 评论 0 原文

我正在纯粹用 JavaScript 开发 OAuth 身份验证流程,我想在弹出窗口中向用户显示“授予访问权限”窗口,但它被阻止了。

如何防止由 window.openwindow.showModalDialog 创建的弹出窗口被不同浏览器的弹出窗口拦截器拦截?

I'm developing an OAuth authentication flow purely in JavaScript and I want to show the user the "grant access" window in a popup, but it gets blocked.

How can I prevent pop up windows created by either window.open or window.showModalDialog from being blocked by the different browsers' pop-up blockers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

遗弃M 2024-09-03 12:04:20

我已经通过使用 setTimeOut 函数来管理它。

setTimeOut(function(){
  window.location.replace("https://www.google.com/");
}, 1000)

✅✅✅✅✅

I have managed this by using setTimeOut function.

setTimeOut(function(){
  window.location.replace("https://www.google.com/");
}, 1000)

✅✅✅✅✅

所谓喜欢 2024-09-03 12:04:20

摆脱这个问题的最简单方法是:

  1. 不要使用 document.open()。
  2. 而是使用 this.document.location.href = location;其中 location 是要加载的 url

例如:

<script>
function loadUrl(location)
{
this.document.location.href = location;
}</script>

<div onclick="loadUrl('company_page.jsp')">Abc</div>

这对我来说非常有效。
干杯

The easiest way to get rid of this is to:

  1. Dont use document.open().
  2. Instead use this.document.location.href = location; where location is the url to be loaded

Ex :

<script>
function loadUrl(location)
{
this.document.location.href = location;
}</script>

<div onclick="loadUrl('company_page.jsp')">Abc</div>

This worked very well for me.
Cheers

从来不烧饼 2024-09-03 12:04:19

@这里
我发现它在所有浏览器中都能正常工作

window.open(URL) || window.location.assign(URL)

@here
I found it's work fine in all browsers

window.open(URL) || window.location.assign(URL)
关于从前 2024-09-03 12:04:19

只需使用 window.location.href = yourUrl 或带有 target='_blank' 的 url

window.open() 有太多问题,如果距离用户操作超过一秒,许多浏览器将其视为弹出窗口并阻止它

Just use window.location.href = yourUrl or a url with target='_blank'

window.open() has too many issues, if it's more than one second from a user action a lot of browsers treat it as a popup and block it

妳是的陽光 2024-09-03 12:04:19

除非回调成功返回,否则我不想创建新页面,因此我这样做是为了模拟用户点击:

function submitAndRedirect {
  apiCall.then(({ redirect }) => {
      const a = document.createElement('a');
      a.href = redirect;
      a.target = '_blank';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
  });
}

I didn't want to make the new page unless the callback returned successfully, so I did this to simulate the user click:

function submitAndRedirect {
  apiCall.then(({ redirect }) => {
      const a = document.createElement('a');
      a.href = redirect;
      a.target = '_blank';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
  });
}
绝對不後悔。 2024-09-03 12:04:18

我尝试了多种解决方案,但他是唯一在所有浏览器中真正对我有用的解决方案

let newTab = window.open();
newTab.location.href = url;

I tried multiple solutions, but his is the only one that actually worked for me in all the browsers

let newTab = window.open();
newTab.location.href = url;

最终幸福 2024-09-03 12:04:18

我的用例:在我的 React 应用程序中,用户单击后会向后端执行 API 调用。根据响应,打开新选项卡,并将 api 响应作为参数添加到新选项卡 URL(在同一域中)。

我的用例中唯一需要注意的是,接收 API 响应需要 1 秒以上的时间。因此,在新选项卡中打开 URL 时,会显示弹出窗口阻止程序(如果它处于活动状态)。

为了避免上述问题,这里是示例代码,

var new_tab=window.open()
axios.get('http://backend-api').then(response=>{
    const url="http://someurl"+"?response"
    new_tab.location.href=url;
}).catch(error=>{
    //catch error
})

摘要:创建一个空选项卡(如上面第 1 行),当 API 调用完成时,您可以使用 url 填充该选项卡并跳过弹出窗口阻止程序。

My use case: In my react app, Upon user click there is an API call performed to the backend. Based on the response, new tab is opened with the api response added as params to the new tab URL (in same domain).

The only caveat in my use case is that it takes more for 1 second for the API response to be received. Hence pop-up blocker shows up (if it is active) when opening up URL in a new tab.

To circumvent the above described issue, here is the sample code,

var new_tab=window.open()
axios.get('http://backend-api').then(response=>{
    const url="http://someurl"+"?response"
    new_tab.location.href=url;
}).catch(error=>{
    //catch error
})

Summary: Create an empty tab (as above line 1) and when the API call is completed, you can fill up the tab with the url and skip the popup blocker.

冰之心 2024-09-03 12:04:17

一般规则是,如果从 javascript 调用 window.open 或类似内容(而不是由直接用户操作调用),则弹出窗口拦截器将会参与。也就是说,您可以调用 window.open 来响应按钮单击,而不会被弹出窗口阻止程序击中,但如果您将相同的代码放入计时器事件中,它将被阻止。调用链的深度也是一个因素 - 一些较旧的浏览器只查看直接调用者,较新的浏览器可以稍微回溯以查看调用者的调用者是否是鼠标单击等。保持其尽可能浅以避免弹出窗口阻止程序。

The general rule is that popup blockers will engage if window.open or similar is invoked from javascript that is not invoked by direct user action. That is, you can call window.open in response to a button click without getting hit by the popup blocker, but if you put the same code in a timer event it will be blocked. Depth of call chain is also a factor - some older browsers only look at the immediate caller, newer browsers can backtrack a little to see if the caller's caller was a mouse click etc. Keep it as shallow as you can to avoid the popup blockers.

混浊又暗下来 2024-09-03 12:04:17

基于 Jason Sebring此处介绍的内容和那里,我找到了适合我的案例的完美解决方案:

带有 Javascript 片段的伪代码:

  1. 立即在用户操作上创建一个空白弹出窗口

     var importantStuff = window.open('', '_blank');
    

    (使用 window.open 的调用“noreferrer”>您需要的任何其他选项。)

    可选:添加一些“等待”信息消息。示例:

    a) 外部 HTML 页面:将上面的行替换为

     var importantStuff = window.open('http://example.com/waiting.html', '_blank');
    

    b) 文本:在上面一行下面添加以下行:

     importantStuff.document.write('正在加载预览...');
    
  2. 准备好后(例如,当 AJAX 调用返回时)填充内容

     importantStuff.location.href = 'https://example.com/finally.html';
    

    或者,如果您根本不需要它,您可以在此处关闭该窗口(例如,如果 ajax 请求失败 - 感谢 @Goose 的评论):

     importantStuff.close();
    

我实际上使用此解决方案进行 mailto 重定向,并且它适用于我的所有浏览器(Windows 7、Android)。顺便说一句,_blank 位有助于 mailto 重定向在移动设备上工作。

Based on Jason Sebring's very useful tip, and on the stuff covered here and there, I found a perfect solution for my case:

Pseudo code with Javascript snippets:

  1. immediately create a blank popup on user action

     var importantStuff = window.open('', '_blank');
    

    (Enrich the call to window.open with whatever additional options you need.)

    Optional: add some "waiting" info message. Examples:

    a) An external HTML page: replace the above line with

     var importantStuff = window.open('http://example.com/waiting.html', '_blank');
    

    b) Text: add the following line below the above one:

     importantStuff.document.write('Loading preview...');
    
  2. fill it with content when ready (when the AJAX call is returned, for instance)

     importantStuff.location.href = 'https://example.com/finally.html';
    

    Alternatively, you could close the window here if you don't need it after all (if ajax request fails, for example - thanks to @Goose for the comment):

     importantStuff.close();
    

I actually use this solution for a mailto redirection, and it works on all my browsers (windows 7, Android). The _blank bit helps for the mailto redirection to work on mobile, btw.

蝶舞 2024-09-03 12:04:17

作为一个好的做法,我认为测试弹出窗口是否被阻止并采取行动以防万一是一个好主意。您需要知道 window.open 有一个返回值,如果操作失败,该值可能为 null。例如,在下面的代码中:

function pop(url,w,h) {
    n=window.open(url,'_blank','toolbar=0,location=0,directories=0,status=1,menubar=0,titlebar=0,scrollbars=1,resizable=1,width='+w+',height='+h);
    if(n==null) {
        return true;
    }
    return false;
}

如果弹出窗口被阻止,window.open将返回null。所以该函数将返回 false。

举个例子,想象一下直接从任何链接调用这个函数
with target="_blank":如果弹出窗口成功打开,则返回
false 将阻止链接操作,否则如果弹出窗口被阻止,
返回 true 将让默认行为(打开新的_blank
窗口)并继续。

<a href="http://whatever.com" target="_blank" onclick='return pop("http://whatever.com",300,200);' >

这样,如果有效的话,您将看到一个弹出窗口,如果有效,您将看到一个空白窗口
不是。

如果弹出窗口未打开,您可以:

  • 打开一个空白窗口,如示例中所示,然后继续
  • 打开一个假弹出窗口(页面内的 iframe)
  • 通知用户(“请允许此站点弹出窗口”)
  • 打开一个空白窗口,然后然后通知用户
    ETC..

As a good practice I think it is a good idea to test if a popup was blocked and take action in case. You need to know that window.open has a return value, and that value may be null if the action failed. For example, in the following code:

function pop(url,w,h) {
    n=window.open(url,'_blank','toolbar=0,location=0,directories=0,status=1,menubar=0,titlebar=0,scrollbars=1,resizable=1,width='+w+',height='+h);
    if(n==null) {
        return true;
    }
    return false;
}

if the popup is blocked, window.open will return null. So the function will return false.

As an example, imagine calling this function directly from any link
with target="_blank": if the popup is successfully opened, returning
false will block the link action, else if the popup is blocked,
returning true will let the default behavior (open new _blank
window) and go on.

<a href="http://whatever.com" target="_blank" onclick='return pop("http://whatever.com",300,200);' >

This way you will have a popup if it works, and a _blank window if
not.

If the popup does not open, you can:

  • open a blank window like in the example and go on
  • open a fake popup (an iframe inside the page)
  • inform the user ("please allow popups for this site")
  • open a blank window and then inform the user
    etc..
唱一曲作罢 2024-09-03 12:04:17

另外瑞士先生的帖子,在我的例子中,window.open是在一个承诺中启动的,这打开了弹出窗口拦截器,我的解决方案是:
在角度:

$scope.gotClick = function(){

  var myNewTab = browserService.openNewTab();
  someService.getUrl().then(
    function(res){
        browserService.updateTabLocation(res.url, myNewTab);

    }
  );
};

browserService:

this.openNewTab = function(){
     var newTabWindow = $window.open();
     return newTabWindow;
}

this.updateTabLocation = function(tabLocation, tab) {
     if(!tabLocation){
       tab.close();
     }
     tab.location.href = tabLocation;
}

这是您可以使用承诺响应而不调用弹出窗口阻止程序打开新选项卡的方法。

In addition Swiss Mister post, in my case the window.open was launched inside a promise, which turned the popup blocker on, my solution was:
in angular:

$scope.gotClick = function(){

  var myNewTab = browserService.openNewTab();
  someService.getUrl().then(
    function(res){
        browserService.updateTabLocation(res.url, myNewTab);

    }
  );
};

browserService:

this.openNewTab = function(){
     var newTabWindow = $window.open();
     return newTabWindow;
}

this.updateTabLocation = function(tabLocation, tab) {
     if(!tabLocation){
       tab.close();
     }
     tab.location.href = tabLocation;
}

this is how you can open a new tab using the promise response and not invoking the popup blocker.

故笙诉离歌 2024-09-03 12:04:17

来自 Google 的 oauth JavaScript API:

http://code.google.com /p/google-api-javascript-client/wiki/Authentication

查看其中显示的区域:

设置身份验证

OAuth 2.0 的客户端实现使用弹出窗口来提示用户登录并批准申请。第一次调用gapi.auth.authorize可以触发弹出窗口阻止程序,因为它间接打开弹出窗口。为了防止弹出窗口阻止程序在身份验证调用时触发,请在客户端加载时调用gapi.auth.init(callback)。当库准备好进行身份验证调用时,将执行提供的回调。

我猜它与上面的真实答案有关,因为它如何解释如果有立即响应,它就不会触发弹出警报。 “gapi.auth.init”正在制作它,以便 api 立即发生。

实际应用

我使用 npm 上的节点护照以及每个提供商的各种护照包制作了一个开源身份验证微服务。我对第 3 方使用了标准重定向方法,为其提供了要返回的重定向 URL。这是程序化的,所以我可以在不同的地方重定向回登录/注册和特定页面。

github.com/sebringj/athu

passportjs.org

from Google's oauth JavaScript API:

http://code.google.com/p/google-api-javascript-client/wiki/Authentication

See the area where it reads:

Setting up Authentication

The client's implementation of OAuth 2.0 uses a popup window to prompt the user to sign-in and approve the application. The first call to gapi.auth.authorize can trigger popup blockers, as it opens the popup window indirectly. To prevent the popup blocker from triggering on auth calls, call gapi.auth.init(callback) when the client loads. The supplied callback will be executed when the library is ready to make auth calls.

I would guess its relating to the real answer above in how it explains if there is an immediate response, it won't trip the popup alarm. The "gapi.auth.init" is making it so the api happens immediately.

Practical Application

I made an open source authentication microservice using node passport on npm and the various passport packages for each provider. I used a standard redirect approach to the 3rd party giving it a redirect URL to come back to. This was programmatic so I could have different places to redirect back to if login/signup and on particular pages.

github.com/sebringj/athu

passportjs.org

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文