18

window.open()默认情况下,从主线程调用会打开新选项卡。

但是,这里每次都打开新窗口(Opera 16 和 Google Chrome 29)

<input type="button" value="Open" onclick="cb1()">

<script type="text/javascript">  
function cb1() {
    setTimeout(wo, 1000); //simple async
}

function wo()
{
   var a = window.open("http://google.com", "w2");
   a.focus();
}
</script>

(大声笑,这是我对使用 JavaScript 在新选项卡(而不是新窗口)中打开 URL 的答案 )。

我如何在选项卡中打开(默认浏览器)?

4

5 回答 5

18

我们遇到了同样的问题,并在 SO 周围寻找答案。我们发现的东西在我们的环境中起作用,提炼出来的智慧如下:

该问题与阻止程序化窗口打开的浏览器弹出窗口阻止程序有关。浏览器允许从主线程上发生的实际用户点击打开窗口。同样,如果您在主线程上调用 window.open ,它将起作用,如上所述。如果您正在使用 Ajax 调用并想在成功时打开窗口,则根据使用 JavaScript 在新选项卡(而不是新窗口)中打开 URL 上的答案,您需要设置async: false哪个有效,因为这会将所有内容保留在主线。

我们无法像那样控制我们的 Ajax 调用,但由于同样的原因,我们找到了另一个可行的解决方案。警告,它有点hacky,考虑到你的限制,可能不适合你。感谢对使用 JavaScript 在新选项卡(而不是新窗口)中打开 URL的不同答案的评论,您在调用之前打开窗口setTimeout,然后在延迟函数中更新它。有几种方法可以做到这一点。在打开窗口时保留对窗口的引用,w = window.open...并在延迟函数中设置w.location或打开目标,window.open('', 'target_name')在该目标中打开window.open('your-url', 'target_name'),并依靠浏览器保留引用。

当然,如果用户有他们的设置以在新窗口中打开链接,这不会改变这一点,但这对 OP 来说不是问题。

于 2014-03-18T04:06:58.260 回答
4

就像其他帖子提到的那样,最好的方法是先打开窗口,然后在回调或异步函数之后设置它的位置

<input type="button" value="Open" onclick="cb1()">

<script type="text/javascript">

function cb1() {
  var w = window.open('', 'w2');
  setTimeout(function () {
    wo(w);
  }, 1000); //simple async
}

function wo(w)
{
  w.location = "http://google.com";
  w.focus();
}
</script>

或者,如果您使用的是 async await,您也会遇到同样的问题。同样的解决方案仍然适用。

public async openWindow(): Promise<void> {
    const w = window.open('', '_blank');
    const url = await getUrlAsync();
    w.location = url;    
}

进一步的增强是在初始页面上打开窗口,通过加载 url 或向该页面写入一些 html 来提供一些快速反馈

public async openWindow(): Promise<void> {
    const w = window.open('', '_blank');
    w.document.write("<html><head></head><body>Please wait while we redirect you</body></html>");
    w.document.close();
    const url = await getUrlAsync();
    w.location = url;    
}

这将防止用户在解析您的 URL 所需的时间内查看空白选项卡/窗口。

于 2019-01-31T11:54:41.820 回答
1

这甚至更“黑客”,但是......

如果您将 window.open 包装在 console.log 中,那么它将起作用。

console.log(window.open('https://someurl', '_blank'))

于 2021-08-09T13:15:10.657 回答
0

如果新窗口作为新选项卡或新实例打开,则取决于用户设置。

于 2014-01-30T14:41:39.790 回答
0

我正在使用NestjsVue3。但我使用这里写的代码解决了它。我刚刚在localhost:8080上获取了从后端发送的令牌。所以我只是切片令牌并将其设置为本地存储,然后将用户重定向到下一页。这将授权用户使用此令牌Vue 3。这样就解决了。你可以改进它,让它变得更好。我就是这样做的,因为我在后端使用了OAuth google-passport而不是 firebase

<script>

methods: {
     googleLogin() {
      const win = window.open(
        "http://localhost:3000",
        "windowname1",
        "width=800, height=600"
      );
      const validateToken = (token) => {
        localStorage.setItem("token", token);
        this.$router.push("/GeneralPage");
        window.clearInterval(pollTimer);
        clearInterval(pollTimer);
        win.close();
      };
      const pollTimer = window.setInterval(async () => {
        try {
          let url = win.document.URL;
          let token = url.slice(22, url.length);
          if (token !== "") {
            localStorage.setItem("token", token);
            this.$router.push("/GeneralPage");
            clearInterval(pollTimer);
            win.close();
            validateToken(token);
            return;
          }
          return;
        } catch (e) {}
      }, 1000);
    },
}
</script>

于 2021-04-05T10:52:37.577 回答