【问题标题】:Ionic: Intercept PDF URLs with cordova-plugin-inappbrowserIonic:使用 cordova-plugin-inappbrowser 拦截 PDF URL
【发布时间】:2019-06-01 07:58:31
【问题描述】:

我正在使用 ionic 3 构建一个 Android/iOS 应用程序,该应用程序仅包含一个由 cordova-plugin-inappbrowser(版本 3.0.0)提供的 web 视图和一个响应式主页。主页包含指向网站以及(在线)PDF 文件的不同链接。

据我所知,Android 中的 webview(我还没有尝试过 iOS)不支持打开 PDF 文件。 这就是为什么我想拦截被调用的 URL,并以其他方式打开它们,如果它们以 '.pdf' 结尾:

import { Component } from '@angular/core';
import {InAppBrowser, InAppBrowserObject, InAppBrowserOptions} from "@ionic-native/in-app-browser";

export class HomePage {

  options : InAppBrowserOptions = {
    location : 'no',//Or 'no'
    hidden : 'no', //Or  'yes'
    clearcache : 'yes',
    clearsessioncache : 'yes',
    zoom : 'no',//Android only ,shows browser zoom controls
    hardwareback : 'yes',
    mediaPlaybackRequiresUserAction : 'no',
    shouldPauseOnSuspend : 'no', //Android only
    closebuttoncaption : 'Close', //iOS only
    disallowoverscroll : 'no', //iOS only
    toolbar : 'no', //iOS only
    enableViewportScale : 'no', //iOS only
    allowInlineMediaPlayback : 'no',//iOS only
    presentationstyle : 'pagesheet',//iOS only
    fullscreen : 'yes'//Windows only
  };

  constructor(private inAppBrowser: InAppBrowser) {
    this.openWithCordovaBrowser('http://url.tohomepage.com');
  }

  public openWithCordovaBrowser(url : string){
    let target = "_self";
    this.browser = this.inAppBrowser.create(url,target,this.options);
    this.browser.on('loadstart').subscribe((event) => {
      if(event.url.endsWith('.pdf'))
      {
        //Open PDF in some other way
      }
    });
    this.browser.on('loadstop').subscribe((event) => {
    });
    this.browser.on('exit').subscribe((event) => {
    });
  }
}

我现在的问题是,当调用 PDF-URL 时,没有触发 3 个事件(loadstart、loadstop、loaderror)。使用通常的 URL,这些事件会按预期触发。 有没有其他方法可以拦截这些电话? (据我所知,这个版本中不存在 beforeload 事件)

感谢任何帮助/提示!


编辑:

我按照建议直接从 github master 安装了 cordova-plugin-inappbrowser。 据我所知,“前加载”通道是在模块中实现的。 但是'beforeload'事件仍然没有触发。 (但“loadstart”适用于非 PDF URL)。

declare var cordova: any;
...

constructor() {
    var iabRef = cordova.InAppBrowser.open("http://someurl.com", "_blank", "beforeload=yes");

    iabRef.addEventListener('beforeload', function(params, callback){
      alert('Beforeload fired');

      // If the URL being loaded is a PDF
      if(params.url.match(".pdf")){
        // Open PDFs in system browser (instead of InAppBrowser)
        cordova.inAppBrowser.open(params.url, "_system");
      }else{
        // Invoke callback to load this URL in InAppBrowser
        callback(params.url);
      }
    });

    iabRef.addEventListener('loadstart', function(params, callback){
      alert('Loadstart fired');
    });
}

【问题讨论】:

    标签: android cordova ionic-framework cordova-plugins inappbrowser


    【解决方案1】:

    所以最后通过一些变通方法我让它工作了:

    declare var cordova: any;
    
    @Component({
      selector: 'page-home',
      templateUrl: 'home.html'
    })
    export class HomePage {
    
      private iabRef;
    
      constructor(private inAppBrowser: InAppBrowser, private platform: Platform, private spinnerDialog: SpinnerDialog, private file: File, private fileTransfer: FileTransfer, private fileOpener: FileOpener) {
    
        this.platform.ready().then(() => {
          if (this.platform.is('android')) {
            this.androidBrowser();
          } else {
            this.iosBrowser();
          }
        });
      }
    
      iosBrowser() {
        let browser = this.inAppBrowser.create("http://someurl.com", "_blank", "location=no,navigationbuttoncolor=#ffffff);
      }
    
      androidBrowser() {
        let that = this;
    
        this.iabRef = cordova.InAppBrowser.open("http://someurl.com", "_blank", "beforeload=yes,location=no");
    
        this.iabRef.addEventListener('beforeload', function(params, callback){
          // If the URL being loaded is a PDF
          if(params.url.match(".pdf")){
            that.openPDF(params.url);
          } else {
            callback(params.url);
          }
        }, false);
    
        this.iabRef.addEventListener('loadstart', function(params, callback){
          that.spinnerDialog.show(null, null, true);
        });
    
        this.iabRef.addEventListener('loadstop', function(params, callback){
          that.spinnerDialog.hide();
        });
    
        this.iabRef.addEventListener('exit', function(params, callback){
          that.platform.exitApp();
        });
      }
    
      openPDF(url: string) {
        let title = url.substring(
          url.lastIndexOf("/") + 1,
          url.lastIndexOf(".pdf")
        );
    
        let path =  this.file.dataDirectory;
    
        const transfer = this.fileTransfer.create();
        transfer.download(url, path + title + '.pdf').then(entry => {
          let url = entry.toURL();
          this.fileOpener.open(url, 'application/pdf');
        });
      }
    }
    

    直接从 GitHub 存储库安装 Cordova 插件后,“beforeload”事件被触发(虽然有时只是在第二次点击 pdf 链接后,但我现在不得不忍受)。 起初我尝试用另一个 cordova.InAppBrowser.open("http://someurl.com/pdffile.pdf", "_system"); 打开 PDF-URL 那行得通,但是,当我回到原来的 inAppBrowser 时,网站就卡住了。按钮和链接显示他们被点击的反馈,但浏览器不再反应。由于我无法解决该问题,我现在正在下载 pdf 文件并使用 FileOpener 插件打开它。当我现在从 pdf 回到应用程序时,浏览器仍然像以前一样工作。

    对于 iOS,我无法像使用 android 一样使用直接 Cordova 插件运行它。因此,如果设备运行的是 iOS,我会使用 ionic native inAppBrowser 插件打开它。 iOS Webview 可以很好地处理 pdf,但无法下载显示的 pdf,我还没有找到解决方案。

    【讨论】:

      【解决方案2】:

      如果您直接从Github master branch 安装cordova-plugin-inappbrowser,则PR #276 添加了一个未发布的功能,它添加了一个beforeload 事件。

      首先直接从master安装插件:

      cordova plugin add https://github.com/apache/cordova-plugin-inappbrowser
      

      然后像这样使用它:

      // Open InAppBrowser on initial page
      var iabRef = cordova.InAppBrowser.open("http://www.someurl.com", "_blank", "beforeload=yes");
      
      // Add beforeload event handler which is called before each new URL is loaded into the InAppBrowser Webview
      iabRef.addEventListener('beforeload', function(params, callback){
          // If the URL being loaded is a PDF
          if(params.url.match(".pdf")){
              // Open PDFs in system browser (instead of InAppBrowser)
              cordova.InAppBrowser.open(params.url, "_system");
          }else{
              // Invoke callback to load this URL in InAppBrowser
              callback(params.url);
          }
      });
      

      【讨论】:

      • 与 'loadstart' 不同,'beforeload' 事件仍未触发。我更新了我的问题。感谢您的帮助!
      • 原来它仍然以某种方式使用“旧”离子原生 inAppBrowser 插件。重置一切解决了它,现在调用'beforeload'。现在,使用cordova.InAppBrowser.open(params.url, "_system"); 打开 PDF 文件可以工作,但是当我从 PDF 返回到原始浏览器时,我无法打开更多链接并且浏览器卡在页面上。有什么想法吗?
      • 不确定,这不是我测试过的场景(在系统浏览器中打开 PDF),但可能是新实现中的错误。如果它可以单独重现,那么open an issue against cordova-plugin-inappbrowser
      • 这里的问题是当前主版本在Android 7或更低版​​本上崩溃
      猜你喜欢
      • 2019-11-07
      • 2021-07-02
      • 2016-07-15
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      相关资源
      最近更新 更多