在Firefox和Safari中在异步函数中使用window.open

6

我所工作的应用程序与一些平台集成,这些平台在用户身份验证方面有一些严格的安全策略,因此我们这边的身份验证也必须以稍微不同的方式处理。这里的细节并不是非常重要。

我正在开发一个新功能,允许用户打开列表中的某些项目,从用户体验的角度来看,最好在新标签页中打开这些项目,因为用户想一次性打开很多项目而不必回到列表并再次找到自己的位置。

因此,为了使其正常工作,我们的API拥有一个redirects端点来处理身份验证。实现细节并不重要,重要的是要知道该端点将接收应从我们的UI提供的URL,并返回带有令牌的重定向URL。

因此,我选择了以下函数,该函数在用户单击按钮时调用

async function openInNewTab() {
  // $ajax is an axios instance that calls the endpoint
  const { url } = await $ajax.post('/redirects', {
    data: {
      url: "myurl.com/route/to/go/to",
      //...
    }
  });

  window.open(url)
}

正如您所见,这非常简单,它从我们的API获取重定向URL,并尝试在新选项卡中打开该URL。这在Chrome浏览器中有效,但在Firefox或Safari浏览器中不起作用,提示用户弹出窗口被阻止。

我很清楚浏览器对弹出窗口有许多规则,以及当它们被阻止时的原因,但在这种情况下,此操作是通过按钮点击由用户交互引发的,唯一的问题是被调用的函数是异步的。

是否有办法使其在Firefox和Safari中工作?该函数在现实网络速度下无法完全正常工作,没有办法通过像链接中的target="_blank"等方式绕过重定向URL,否则身份验证将无法正常进行,这是我们的应用程序运行方式。


弹出窗口拦截程序没有将其视为用户操作。看起来很奇怪,你为什么不直接在新窗口中发布并进行重定向呢? - epascarello
1个回答

3

这里有两种可能的解决方法。

它们都非常相似,但通过我的测试,似乎当涉及解析事件作为弹出窗口时,Safari最严格。

其中一种方法适用于所有主要浏览器 (基于Chromium 的浏览器、Firefox 和 Safari),但感觉有点取巧。

在此处找到了这个解决方法:https://dev59.com/GWIj5IYBdhLWcg3wCxB0#70463940

const { url } = await $ajax.post('/redirects', {
  data: {
    url: "myurl.com/route/to/go/to",
    //...
  }
});

setTimeout(() => {
  window.open(url, "_blank");
});

另一种解决方案是,虽然这种方法在Safari上似乎不总是有效,有时会被阻止(看起来是随机的)

const newWindow = window.open('about:blank', '_blank');

const { url } = await $ajax.post('/redirects', {
  data: {
    url: "myurl.com/route/to/go/to",
    //...
  }
});

newWindow.location.href = url;

现在似乎setTimeout的方法不起作用了? - Crashalot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接