关于android:Ionic:使用cordova-plugin-inappbrowser拦截PDF URL

Ionic: Intercept PDF URLs with cordova-plugin-inappbrowser

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

据我了解,Android(我尚未尝试过iOS)中的Web视图不支持打开PDF文件。
这就是为什么我想拦截被调用的URL,并以其他方式打开它们(如果它们以" .pdf"结尾)的原因:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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主机安装了cordova-plugin-inappbrowser。
据我所知," beforeload"通道是在模块中实现的。
但是" beforeload"事件仍然没有触发。 (但是," loadstart"适用于非PDF URL)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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');
    });
}

如果直接从Github主分支安装cordova-plugin-inappbrowser,则PR#276添加了一个未发布的功能,该功能会添加一个beforeload事件。

首先直接从master安装插件:

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

然后使用如下所示的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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);
    }
});


因此,终于有了一些解决方法,我使其得以工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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,但我还没有找到解决方法。