如何在 Chrome 打包应用程序中从 Web 视图中的链接打开新窗口

2023-11-26

为了显示来自横幅广告交换的广告,我正在加载一个包含链接到广告服务器的 iframe 的 Web 视图。通过一些 JavaScript,我可以将广告链接目标设置为“_blank”,以便广告将在单独的浏览器窗口中打开,否则它将在同一个小网络视图中打开。

然而它不起作用,我在控制台中得到了这个:

<webview>: A new window was blocked.

有什么想法如何做到这一点?


问题是,默认情况下,Web 视图不会让访客打开任意窗口。相反,它会发出一个“newwindow”事件,您可以拦截该事件并决定如何处理它。以一种不那么可怕的形式,这看起来像:

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create(
    'main.html',
    { 'width': 1000, 'height': 1000 },
    function(win) {
      win.contentWindow.onload = function() {
        var webview = win.contentWindow.document.querySelector('#my_webview');
        webview.addEventListener('newwindow', function(e) {
          e.preventDefault();
          // e.targetUrl contains the target URL of the original link click
          // or window.open() call: use it to open your own window to it.
          // Something to keep in mind: window.open() called from the
          // app's event page is currently (Nov 2013) handicapped and buggy
          // (e.g. it doesn't have access to local storage, including cookie
          // store). You can try to use it here and below, but be prepare that
          // it may sometimes produce bad results.
          chrome.app.window.create(e.targetUrl, ...);
        });
      };
    }
  );
});

鉴于您所描述的条件,我认为这应该对您有用。

在更糟糕的情况下,某些网站可能会打开新的窗口/选项卡,如下所示:

function open(href) {
    var w = window.open('', '_blank');
    w.opener = null;
    w.document.write(
      '<META HTTP-EQUIV="refresh" content="0; url=' + href + '">');
    w.document.close();
}

如果这样的网站被包裹在 webview 中,一切都会变得更加困难:上面“newwindow”处理程序中的 e.targetUrl 将包含“about:blank”,因此无需修改,代码将打开一个空白窗口/选项卡。要拦截来自访客的后续重定向,应用程序还必须使用chrome.webRequest API(该文档似乎仅适用于扩展,但该 API 也已可用于稳定渠道中的打包应用程序):

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create(
    'main.html',
    { 'width': 2000, 'height': 1000 },
    function(win) {
      win.contentWindow.onload = function() {
        var webview = win.contentWindow.document.querySelector('#webview');
        webview.addEventListener('newwindow', function(e) {
          e.preventDefault();
          if (e.targetUrl !== 'about:blank') {
            // Easy case where the original link or window.open()
            // already contains a target URL.
            newWindow_openInTab(e.targetUrl);
          } else {
            // Harder case where the guest first opens a blank
            // window and then redirects it via a
            // 'META HTTP-EQUIV="refresh"'.
            newWindow_openInTabAndInterceptRedirect(e.window);
        });
      };
    }
  );
});

function newWindow_openInTab(url) {
  chrome.app.window.create(url, ...);
}

function newWindow_openInTabAndInterceptRedirect(newWindow) {
  // Create an invisible proxy webview to listen to redirect
  // requests from |newWindow| (the window that the guest is
  // trying to open). NOTE: The proxy webview currently has to
  // live somewhere in the DOM, so we append it to the body.
  // This requirement is in the process of being eliminated.
  var proxyWebview = document.createElement('webview');
  document.body.appendChild(proxyWebview);

  // Listen to onBeforeRequest event (chrome.webRequest API)
  // on proxyWebview in order to intercept newWindow's redirects.
  var onBeforeRequestListener = function(e) {
    // Only consider top-level non-blank redirects.
    if (e.type === "main_frame" && e.url !== 'about:blank') {
      chrome.app.window.create(e.url, ...);
      // Don't need proxyWebview anymore.
      document.body.removeChild(proxyWebview);
      // Handled this redirect: cancel further processing.
      return { cancel: true };
    } else {
      // Ignored this redirect: proceed with default processing.
      return { cancel: false };
    }
  };
  proxyWebview.onBeforeRequest.addListener(
    onBeforeRequestListener,
    { urls: [ "*://*/*" ] },
    [ 'blocking' ]
  );

  // Attach |newWindow| to proxyWebview. From the original
  // webview guest's point of view, the window is now opened
  // and ready to be redirected: when it does so, the redirect
  // will be intercepted by |onBeforeRequestListener|.
  newWindow.attach(proxyWebview);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Chrome 打包应用程序中从 Web 视图中的链接打开新窗口 的相关文章

随机推荐

  • Android 文件描述符泄漏调试

    我们公司有很多在虚拟 真实设备上运行的用户界面测试 运行一段时间后测试随机崩溃 我认为这是文件描述符超出的结果 我使用 ls proc PID fd wc l and lsof p PID 但它并没有多大帮助 lsof 中的大多数行看起来像
  • Athena 的 .csv.metadata 文件的数据格式是什么?

    的数据格式是什么 csv metadata由 Amazon Athena 编写的文件 除了每个查询的输出文件之外 还有一个元数据文件 看起来它描述了结果的架构 我认为这就是雅典娜用来创建ResultSet ResultSetMetadata
  • Oracle 中表行的创建日期时间是多少?

    昨天我的朋友 BI 专家 向我解释了一个预言机问题 有一个 Oracle 数据库包含大量数据 但它们不会为每个表创建列来存储每行的创建日期时间 所以在这种情况下他如何获得每行的创建日期时间 时间戳 每行都有自己的系统更改号 SCN 这精确地
  • 蟒蛇 |为什么访问实例属性比访问本地慢?

    import timeit class Hello def init self self x 5 def get local attr self x self x 10x10 x x x x x x x x x x x x x x x x
  • 数据流模板 Cloud Pub/Sub 主题与 BigQuery 订阅

    我正在设置一个简单的概念验证来学习 Google Cloud 中的一些概念 特别是 PubSub 和 Dataflow 我有一个 PubSub 主题greeting 我创建了一个简单的云函数 用于向该主题发送发布消息 const escap
  • 使用linux宏access_ok()有什么意义

    我一直在做一些研究 我对这个宏有点困惑 希望有人能给我一些指导 我有一些 ioctl 代码 我继承的 而不是编写的 它做的第一件事是检查是否access ok 在继续从用户空间复制数据之前 define lddk copy from use
  • 找不到“React/RCTBridgeModule.h”文件

    在 xcode 上构建反应本机 iOS 应用程序时出现此错误 npm install 和 rpm 链接后开始出现此错误反应本机FS图书馆 但在网上搜索解决方案后 我注意到很多人在安装其他 React Native 库时遇到了同样的错误 A
  • Kotlin - 使用 Persistence Room:runtime lib 从 Room 数据库返回新插入的 id

    我正在尝试使用 Kotlin 在 Room 数据库中插入用户记录 它工作得很好 现在我想返回新插入的记录id来检查Room数据库中的记录是否成功插入 但是当我在插入方法中应用 Long 返回类型并运行代码时 我收到以下错误 错误 方法返回
  • Vec::new() 如何知道请求的元素类型是什么?

    我可以创建任何类型的向量 如下所示 let mut vec Vec
  • Bootstrap 流体布局 - 侧边栏的固定宽度

    我有一个基于 Twitter Bootstrap 的流畅布局 div class container fluid div class row fluid div class span2 div div class span10 div di
  • spring boot 包不存在错误

    我正在编译我的项目mvn clean package 并失败了package does not exist 详细命令 获取jar文件target xxxx jar通过跑步mvn clean package在源项目中 通过运行安装此 jar
  • CORS、withCredentials 和第三方 cookie

    我正在尝试执行 CORS GET 来发送 cookie 我已经设置了所有标题 access control allow origin access control allow credentials access control allow
  • 过程声明与同名事件或过程的描述不匹配

    我只是新手 尝试用Visual Basic 6编写一个简单的程序 代码几乎与课本上的相同 它本来是一种绘画程序 令人惊讶的是 它无法通过该问题标题中给出的错误进行编译 这是代码 Option Explicit Dim Col As Long
  • Python:如何从请求响应中读取excel文件?

    我正在使用 requests 库以流的形式下载 Excel 文件 r requests get my url stream True 我想读取这个excel文件中的数据 为此我可以尝试使用pandas 但我不确定如何从收到的响应中读取文件
  • Android Studio 重复生成的文件

    Android studio 不断创建生成的类 即使它们已经存在 我猜这个问题与 NavigationArgs 有关 但它总是给出一些重复错误 现在解决我的问题的唯一方法是每次运行应用程序之前清理整个项目 有谁知道如何解决这个问题 我如何知
  • 从文本文件中提取单词

    假设您有一个如下所示的文本文件 http www gutenberg org files 17921 17921 8 txt 有谁有好的算法或开源代码来从文本文件中提取单词 如何获取所有单词 同时避免特殊字符 并保留 it s 等内容 我在
  • 以非 root 用户身份在 Docker 容器中运行不受信任的代码有哪些潜在的安全问题?

    到目前为止 我已经看到了大量关于 Docker 如何没有足够隔离以允许任意容器在多租户环境中运行的文章 这是有道理的 如果它是 Docker 中的根 则将其视为主机中的根 那么非 root 又如何呢 如果我想获取一些不受信任的代码并在容器中
  • 替换 numpy 数组中的元素避免循环

    我有一个相当大的一维 numpy 数组 Xold 具有给定值 这些值应为 根据 2d numpy 数组 Y 指定的规则替换 一个例子是 Xold np array 0 1 2 3 4 Y np array 0 0 1 100 3 300 4
  • esbuild 不捆绑文件

    我正在尝试使用 esbuild 在 npm 项目中捆绑和缩小我的文件 它正在最小化我传入的每个文件 但它不是捆绑 它给我一个错误 当有多个文件时我必须使用 outdir 然而 这让我恢复了所有这些文件 最小化后 放在一个文件夹中 这不是我想
  • 如何在 Chrome 打包应用程序中从 Web 视图中的链接打开新窗口

    为了显示来自横幅广告交换的广告 我正在加载一个包含链接到广告服务器的 iframe 的 Web 视图 通过一些 JavaScript 我可以将广告链接目标设置为 blank 以便广告将在单独的浏览器窗口中打开 否则它将在同一个小网络视图中打