Pdf.js: IE 11-Kompatibilität von Angular + pdf.js aktivieren

Erstellt am 24. März 2017  ·  10Kommentare  ·  Quelle: mozilla/pdf.js

Aufbau:

  • Webbrowser und seine Version: IE 11
  • Betriebssystem und seine Version: Beliebig
  • PDF.js-Version: 1.4.0
  • AngularJs-Version: 1.5.11

Schritte zum Reproduzieren des Problems:

  1. Verwenden Sie AngularJS 1.5.11 mit automatischem Bootstrapping
  2. Binden Sie PDF.js Version 1.4.0 VOR den script-Tags von Angular ein

Was ist das erwartete Verhalten? (Screenshot hinzufügen)

  • Angular arbeitet perfekt mit PDF.js zusammen
  • PDF.js umschließt fehlende API in Funktionen, die die Shimmed-Version verwenden, wenn die native nicht verfügbar ist.

Was schief gelaufen ist? (Screenshot hinzufügen)

  • Siehe https://github.com/angular/angular.js/issues/15772
    Derzeit definiert pdf.js document.currentScript, aber weder link.origin noch link.protocol. Wenn winklig startet, prüft es, ob es erlaubt ist, automatisch zu booten, es prüft auf currentScript und geht davon aus, dass dies ausreicht, um den IE zu filtern, dh wenn currentScript nicht definiert ist, können wir automatisch booten. Diese Prüfung funktioniert nicht in Kombination mit pdf.js.

Bibliotheken sollten keine Eigenschaften von Objekten ändern, die sie nicht besitzen, da dies zu Problemen wie diesen führt. Wenn sie eine bestimmte API benötigen, die in einigen unterstützten Umgebungen fehlt, können sie deren Verwendung in eine Funktion einschließen, die die Shimm-Version verwendet, wenn die native nicht verfügbar ist.

Link zu einem Viewer (sofern auf einer anderen Website als mozilla.github.io/pdf.js oder als Firefox/Chrome-Erweiterung gehostet):
http://plnkr.co/edit/YFCQM2Px0QU0KnGzsAlM?p=preview

1-other

Alle 10 Kommentare

Klingt so, als würde man die Schuld von der etwas IE11-unvollständigen Sicherheitsüberprüfung Angular-Logik auf PDF.js-Polyfill verlagern ... in Ordnung. Als einfacher Fehler markieren, um diese Lücke zu schließen:

  1. document.location.origin muss auf neue URL(document.location.href).origin gesetzt werden, wenn die Eigenschaft 'origin' fehlt
  2. HTMLScriptElement.prototype soll die Ursprungs- und Protokoll-Getter mit der gleichen Logik wie oben haben.

@yurydelendik Für mich ist dies analog zu der Situation, in der einige Web-APIs ihre Namen ändern mussten, weil MooTools partielle Polyfills anwendete und Code im Web abhängig davon begann.

Polyfilling ist riskant, IMO sollte es nur mit vollständigen Polyfills und nur in finalen Apps erfolgen, nicht in Bibliotheken. Wenn Bibliotheken eine bestimmte API benötigen, die nicht überall verfügbar ist, sollten sie die native API in eine Dienstprogrammfunktion einschließen und diese Funktion verwenden. das entfernt die ganze Klasse möglicher Fehler wie diese.

Kurz gesagt: Bibliothekscode sollte keine Objekte ändern, die er nicht besitzt, zB native Browser-Globals.

Polyfilling ist riskant

@mgol oh, ich stimme zu. Die gesamte PDF.js-Viewer-Anwendung muss sich in einer eigenen Sandbox befinden (ich empfehle iframe), aber die Leute verwenden sie weiterhin in größeren Apps. Wir müssen also entsprechend reagieren.

Bibliothekscode sollte keine Objekte ändern, die er nicht besitzt, zB native Browser-Globals.

Nehmen wir ein anderes Beispiel, ohne typisierte Arrays und Promise PDF.js-Bibliothek nicht gleich. Und indem wir globale Objekte nicht ändern, würden wir unseren Code für die meisten modernen Browser unlesbar und wahrscheinlich weniger leistungsfähig machen.

Nehmen wir ein anderes Beispiel, ohne typisierte Arrays und die Promise PDF.js-Bibliothek wäre nicht dasselbe. Und indem wir globale Objekte nicht ändern, würden wir unseren Code für die meisten modernen Browser unlesbar und wahrscheinlich weniger leistungsfähig machen.

Nicht unbedingt. Sie könnten Ihren eigenen internen Satz von Variablen behalten, die Globals beschatten. Dies deckt möglicherweise nicht alle Fälle ab, aber zumindest sollten Versprechen in Ordnung sein. Etwas wie:

var Promise = window.Promise || PROMISE_POLYFILL;

oben in PDF.js. In diesem Fall berühren Sie das Globale nicht und können weiterhin Promise in Ihrem Code ohne Änderungen verwenden.

Dies sollte auch die Leistung in modernen Browsern nicht beeinträchtigen, da es sich um einen einfachen Alias ​​für sie handelt.

Ich verstehe, dass es möglicherweise nicht in allen Fällen so einfach ist (z. B. wenn nur einige Methoden mehrfach gefüllt werden müssen)

PDF.js-Code wird umgewandelt, um ES6-Module zu verwenden. Der obige Ansatz kann atm problematisch sein, es sei denn, ein Verpacker stellt automatisch ein Polyfill bereit.

Ich möchte dieses Problem nicht in eine Diskussion über Winkellogik oder pdf.js-Kompatibilitätsansatz verwandeln. Eine PR ist willkommen :)

Lassen Sie uns dieses Problem mit dem anderen Gedanken schließen, da es nicht behoben werden kann. Es gibt keine Bestätigung dafür, dass Angular+PDF.js+IE11 in der realen Welt verwendet wird. Wenn ja, kann die Korrektur auf der Winkelseite einfach durch Patchen von Angular.js vorgenommen werden.

Hey, ich weiß, das ist ein altes Thema, aber ich stoße auf das oben beschriebene Problem.

Ich habe ein Projekt, in dem ich Angular 5 mit PDF.js verwende und ich muss IE11 unterstützen. Ich bin ein Neuling bei Angular, daher bin ich mir nicht sicher, wie ich Angular.js "patchen" würde - können Sie mir eine Anleitung geben, wie ich diesen Fehler umgehen kann? Danke im Voraus.

@elliotstoner Bei diesem Problem geht es um die AngularJS-Kompatibilität, nicht um Angular (2+) und gilt nur, wenn Sie ng-app anstelle von manuellem Bootstrapping verwenden. Angular 2+ unterstützt nicht einmal automatisches Bootstrapping, daher tritt dieses Problem dort nicht auf.

@mgol Ah ok - dann erstelle ich ein neues Problem, danke.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen