Ionic:使用cordova-plugin-inappbrowser拦截PDF网址

7ivaypg9  于 2022-11-15  发布在  Ionic
关注(0)|答案(3)|浏览(193)

我正在用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'通道在模块中实现了。但是'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');
    });
}
yvfmudvl

yvfmudvl1#

如果您直接从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);
    }
});
xa9qqrwz

xa9qqrwz2#

最后,通过一些变通方法,我让它成功了:

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时,网站卡住了。按钮和链接显示反馈,他们被点击了,但浏览器不再有React。由于我无法解决这个问题,我现在下载PDF文件,并用FileOpener插件打开它。当我现在从PDF返回应用程序时,浏览器仍然像以前一样工作。
对于iOS,我无法像在android上那样直接使用Cordova插件来运行它。因此,如果设备运行iOS,我可以使用ionic原生的inAppBrowser插件来打开它。iOS Webview可以很好地运行pdf文件,尽管无法下载显示的pdf文件,对此我还没有找到解决方案。

6tqwzwtp

6tqwzwtp3#

"你可以用这种方式"

downloadFile(url: string) {
    
    if (this.platform.is('ios')) {
      this.pdfFileOpen(url, this.file.syncedDataDirectory);
    } else {
      this.pdfFileOpen(url, this.file.dataDirectory);
    }
   
  }

  pdfFileOpen(url, fileDir) {

    const pdfFileName = url.split('/')[4]
    this.file.createDir(fileDir, 'FolderName', true)
    .then(resp => {
      
      const fileTransfer: FileTransferObject = this.transfer.create();
      fileTransfer.download(url, resp.toURL() + pdfFileName)
        .then(entry => {
          
          this.fileOpener.showOpenWithDialog(resp.toURL() + pdfFileName, 'application/pdf');
        
        });

      });
  }

相关问题