使用 JavaScript 在新 window/tab(target=_blank) 中打开特征检测

Feature detect opening in a new window/tab(target=_blank) with JavaScript

根据我的研究:

我需要检测此功能何时不可用。不可能?

补充说明

我正在尝试检测是否可以通过 target=_blank 打开一个新的 window。例如,UIWebView [应用内浏览器] 可以阻止 target=_blank 按预期工作 [它只是在同一个 window 而不是新的打开]。我需要一个解决方案来指示何时由于浏览器限制(例如 UIWebView 情况)而无法打开新的 window。不幸的是,弹出窗口阻止程序阻止检查此类功能,因为它们永远不允许在没有用户输入(即点击)的情况下打开新的 window 被绕过。

你不会有 100% 可靠的东西。

Simply attempting to open a new window with JS triggers popup blockers; making it an unreliable way to test if a new window can be opened.

你是对的,它绝对不可靠...... window.open() 被阻止(即使使用像 window.open(url, '_blank');window.focus(); 这样的技巧),click() 也被阻止(在 link 包含 target="_blank"),就像 evt = document.createEvent("MouseEvents");evt.initEvent("click", true, true);...

但无论如何:如果 WebView 不允许在新选项卡中打开 link,那么它将正常工作。但是正如您所暗示的那样,Webview 可能会授权它。在这种情况下,您将不知道自己是否在 webview 中。很容易检测在新标签中打开的 link 是否最终以相同的方式打开(可以在未显示的 iframe 中的 javascript 中测试),但如果 link 是在浏览器中打开,您无法知道(想象一下使用 javascript 代码从应用程序在浏览器中打开新选项卡的用户体验......)。正如 Dave Alperovich 所说,如果不尝试,您无法提前知道什么会被阻止。所以你不应该往那边看。

没有可靠的功能或行为可以将 Webview 与网络浏览器区分开来。在 webview 中,您拥有在浏览器中获得的所有内容(cookies、WebStorage ...)。用户代理有其不完善之处,但在许多情况下都可以使用。有解释 here or here 构建它。

根据 OP 要求,我已经对其进行了测试。它有效。如果启用了弹出窗口阻止程序,我将捕获它,因此我将获得一种可靠的方式来了解它是否已启用。在这种情况下,我只是发送一个警报,但你可以做任何你想做的事情。

代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Testing Pop-up Blocker</title>
<script>
function openPopUp(urlToOpen) {
  var popup_window=window.open(urlToOpen,"myWindow","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=yes, width=400, height=400");            
  try {
    popup_window.focus();   
  }
  catch (e) {
    alert("Pop-up Blocker is enabled! Please add this site to your exception list.");
  }
}
</script>
</head>
<body onload="openPopUp('http://www.google.com'); return false;">
<p>Testing Pop-up Blocker</p>
</body>
</html>

这就是我得到的,因为弹出窗口拦截器已启用。