Skriptdatei, die nach Inline-Skript mit CDN oder externer Domäne bei HTML-Injizierung ausgeführt wird

8

Ich habe ein Problem mit der HTML-Injektion in ein bereits geladenes DOM, in dem das Inline-JavaScript geladen wird, nachdem die Skriptdatei heruntergeladen wurde. Von dem, was ich weiß, sollte dies nicht async sein und das Inline-Skript sollte nach der Skriptdatei ausgeführt werden. Dies funktioniert, wenn der Domänenname mit der aufrufenden Seite identisch ist, aber die Verwendung eines CDN oder sogar einer Subdomäne das Gleiche bewirkt. Gibt es etwas, was ich tun sollte, um zu überarbeiten, wie ich diese anrufe? Ich schwöre, das hat früher geklappt, als ich das CDN über eine Woche lang hatte, aber vielleicht habe ich dieses Problem nie verstanden.

Konsole

%Vor%

JavaScript

%Vor%     
Mike Flynn 24.01.2016, 14:12
quelle

5 Antworten

3

Eine Möglichkeit besteht darin, die jquery-Funktion getScript () zu verwenden.

Am besten verwenden Sie jedoch natives JavaScript, um die Skriptdatei zu laden und dann das Inline-Skript auszuführen.

Vielleicht habe ich die Frage nicht klar verstanden.

Bearbeiten: Dies ist ein Zitat aus der HTML5 Spezifikation für Skriptelemente.

  

Wenn das Element ein src-Inhaltsattribut hat, führen Sie diese Unterschritte aus:

     

Sei src der Wert des src-Attributs des Elements.

     

Wenn src die leere Zeichenfolge ist, stellen Sie eine Aufgabe in die Warteschlange, um ein einfaches benanntes Ereignis auszulösen   Fehler am Element, und brechen Sie diese Schritte ab.

     

Lösen Sie src relativ zum Element auf.

     

Wenn der vorherige Schritt fehlgeschlagen ist, stellen Sie eine Aufgabe in die Warteschlange, um ein einfaches benanntes Ereignis auszulösen   Fehler am Element, und brechen Sie diese Schritte ab.

     

Führen Sie einen potenziell CORS-fähigen Abruf der resultierenden absoluten URL durch,   wobei der Modus der aktuelle Zustand des Crossorigins des Elements ist   Inhaltsattribut, wobei der Ursprung der Ursprung des Skriptelements ist   Dokument, und das Standardursprungsverhalten ist auf taint eingestellt.

     

Die auf diese Weise erhaltene Ressource kann entweder CORS-gleicher Herkunft sein   oder CORS-Kreuzursprung. Dies wirkt sich nur auf die Fehlerberichterstattung aus.

     

Aus Leistungsgründen können Benutzerprogramme möglicherweise das Skript abrufen (z. B.   oben definiert), sobald das Attribut src gesetzt ist, stattdessen in der   hoffe, dass das Element in das Dokument eingefügt wird (und dass das   crossorigin Attribut wird in der Zwischenzeit keinen Wert ändern). In jedem Fall,   Sobald das Element in das Dokument eingefügt wurde, muss die Ladung haben   wie in diesem Schritt beschrieben gestartet. Wenn die UA solche durchführt   Prefetching, aber das Element wird nie in das Dokument eingefügt, oder die   src Attribut wird dynamisch geändert, oder das Crossorigin Attribut ist   dynamisch geändert, dann führt der Benutzeragent das Skript nicht aus   so erhalten, und der Abrufprozess wird effektiv gewesen sein   verschwendet.

     

Dann die erste der folgenden Optionen, die die Situation beschreibt   muss befolgt werden:

     

Wenn das Element ein src-Attribut hat und das Element eine Verzögerung hat   Attribut, und das Element wurde als "Parser-eingefügt" markiert, und   Das Element hat kein Async-Attribut. Das Element muss hinzugefügt werden   bis zum Ende der Liste der Skripte, die beim Ausführen des Dokuments ausgeführt werden   hat das mit dem Dokument des Parsers verknüpfte Parsing beendet   erstellt das Element.

     

Die Aufgabe, die die Netzwerkaufgabenquelle einmal in der Aufgabenwarteschlange platziert   Der Abrufalgorithmus muss abgeschlossen sein und das Element "bereit für" festlegen   parser-executed "flag. Der Parser wird das Skript ausführen.

     

Wenn das Element ein src-Attribut hat und das Element markiert wurde   als "Parser-eingefügt", und das Element hat kein Async-Attribut   Das Element ist das ausstehende Skript zum Blockieren der Analyse des Dokuments von   der Parser, der das Element erstellt hat. (Es kann nur einen solchen geben   Skript pro Dokument gleichzeitig.)

     

Die Aufgabe, die die Netzwerkaufgabenquelle einmal in der Aufgabenwarteschlange platziert   Der Abrufalgorithmus muss abgeschlossen sein und das Element "bereit für" festlegen   parser-executed "flag. Der Parser wird das Skript ausführen.

     

Wenn das Element kein src-Attribut hat und das Element wurde   als "parser-inserted" gekennzeichnet und entweder der Parser, der die   Skript ist ein XML-Parser oder ein HTML-Parser, dessen Verschachtelung des Skripts erfolgt   level ist nicht größer als eins, und das Dokument des HTML-Parsers oder   Der XML-Parser, der das Skriptelement erstellt hat, hat ein Stylesheet   blocking scripts Das Element ist das ausstehende Parsing-Blocking-Skript von   das Dokument des Parsers, der das Element erstellt hat. (Es kann nur   ein Dokument pro Dokument gleichzeitig sein.)

     

Setzen Sie das Flag "Ready to Parser-executed" des Elements. Der Parser wird   handle das Ausführen des Skripts.

     

Wenn das Element ein src-Attribut hat, kein Async-Attribut   und hat nicht das Flag "force-async" gesetzt Das Element muss hinzugefügt werden   bis zum Ende der Liste der Skripte, die in Kürze ausgeführt werden   wie möglich mit dem Dokument des Skriptelements bei der   Zeit die Vorbereitung eines Skriptalgorithmus gestartet.

     

Die Aufgabe, die die Netzwerkaufgabenquelle einmal in der Aufgabenwarteschlange platziert   Der Abrufalgorithmus muss die folgenden Schritte ausführen:

     

Wenn das Element jetzt nicht das erste Element in der Skriptliste ist   das wird so schnell wie möglich ausgeführt, zu dem es hinzugefügt wurde   oben, markieren Sie das Element als bereit, brechen Sie diese Schritte jedoch ab   Ausführen des Skripts noch nicht.

     

Ausführung: Führen Sie den Skriptblock aus, der dem ersten Skript entspricht   Element in dieser Liste von Skripten, die in der Reihenfolge ausgeführt werden, sobald   möglich.

     

Entfernen Sie das erste Element aus dieser Liste von Skripten, die ausgeführt werden   so schnell wie möglich.

     

Wenn diese Liste von Skripten so schnell wie möglich ausgeführt wird   ist noch nicht leer und der erste Eintrag wurde bereits als markiert   bereit, dann springen Sie zurück zum Schritt mit der Bezeichnung Ausführung.

     

Wenn das Element ein src-Attribut hat Das Element muss zu dem hinzugefügt werden   Satz von Skripten, die so schnell wie möglich vom Dokument ausgeführt werden   des Skriptelements zur Zeit der Vorbereitung eines Skriptalgorithmus   gestartet.

     

Die Aufgabe, die die Netzwerkaufgabenquelle einmal in der Aufgabenwarteschlange platziert   Der Abrufalgorithmus hat den Scriptblock und ausgeführt   Entfernen Sie dann das Element aus der Gruppe von Skripten, die als ausgeführt werden   so bald wie möglich.

     

Andernfalls muss der Benutzeragent den Skriptblock sofort ausführen.   auch wenn andere Skripte bereits ausgeführt werden. Ein externes holen   Das Skript muss das load-Ereignis des Dokuments des Elements verzögern, bis   Aufgabe, die von der Quelle der Netzwerkaufgabe einmal in die Warteschlange gestellt wird   wurde abgerufen (oben definiert) wurde ausgeführt.

Davon denke ich, dass Ihre "externe" Datei nach dem Inline-Skriptblock geladen wird. Ich würde daher die Funktion "getScript ()" von jquery verwenden, um sicherzustellen, dass das Skript vor dem Inline-Skriptblock geladen wird.

    
brannmar 26.01.2016, 15:31
quelle
0

Ich habe zwei Theorien:

  1. Es kann sein, dass im externen Skript etwas vorhanden ist, das die Erstellung des app.viewModel.members-Objekts verzögert (entweder ein Timeout oder ein Ereignishandler, dessen Ausführung eine Weile dauert). Dies kann leicht getestet werden, indem Sie in Ihrem Inline-Skript ein langes Timeout setzen (z. B. 5000 + ms) und dann prüfen, ob das Modellobjekt existiert.

  2. Beim Laden eines Originalskripts passiert etwas Ungewöhnliches.

In diesem Fall könnten Sie versuchen, die Ausführung Ihres Inline-Skripts zu verzögern, indem Sie Folgendes tun:

%Vor%

oder fügen Sie einfach Ihren Inline-Code in eine externe .js-Datei ein und rufen Sie ihn mit dem Flag "deferred" auf:

%Vor%     
vtosh 30.01.2016 01:14
quelle
0

Dies ist ein häufiges Problem in der Injektionsszenerie. Es tritt aufgrund der variablen Verzögerungen in der Skriptverfügbarkeit sowie aufgrund der parallelen und unterschiedlichen Implementierungen in verschiedenen Browsern auf.

Es gibt 3 Optionen, abhängig davon, ob der Quellcode zur Bearbeitung verfügbar ist oder nicht und ob mehr als 2 Abhängigkeiten zwischen den Skriptdateien existieren.

Option 1. Verwenden des Defer-Attributs im Skript-Tag

Diese Option kann verwendet werden, wenn beide Skripts remote (dh nicht inline) sind

"defer" zeigt dem Browser an, dass das Skript ausgeführt werden muss, nachdem das Dokument analysiert wurde (zitiert aus MDN). Dies gilt nur für Remote-Skripts (nicht inline) mit dem Attribut "src".

Ссылка

Sie können es wie folgt verwenden.

Defer wird in den meisten Browsern unterstützt, und ich habe in Chrome, Firefox, Webkit auf Tizen und Safari validiert:

Ссылка

Um ein konkretes Beispiel für die oben genannten Fälle zu geben, siehe unten. Beachten Sie, dass die unten stehenden Informationen in Firefox, Chrome, IE11, Safari auf dem iPhone und Webkit auf Tizen validiert wurden.

Fall 1:

Viele Javascript-Dateien - Alle unabhängig:

Wenn keine Abhängigkeit besteht, ermöglicht das Attribut "defer", dass der HTML-Code schnell geladen wird. Das Skript übernimmt nach dem Download ohne Probleme (unter der Voraussetzung onload etc.).

Fall 2:

Zwei Javascript-Dateien test1.js und test2.js - Eins abhängig vom anderen:

Wenn test2.js vom Laden von test1.js abhängig ist, sollte das Skript-Tag für test2.js "only" das Defer-Attribut haben.

Diese Verwendung wird in

angezeigt

Ссылка

Falsche Verwendung wird in

angezeigt

Ссылка (Beide Skripte haben kein Defer-Tag - dies schlägt fehl) Ссылка (Beide Skripte haben ein defer-Tag - dies schlägt auch fehl)

Async-Verwendung, die nicht funktioniert, ist

Ссылка (dies schlägt fehl)

Wo passt "Aufschub" nicht den Bedürfnissen?

Wenn die Funktionalität auf mehrere JS-Dateien verteilt ist (zB n), müssen alle "n-1" heruntergeladen werden, bevor "n" Dateien verarbeiten können, auch wenn das "defer" -Attribut vorhanden ist Bei allen Skriptquellen-Tags wird es irrelevant, da die Reihenfolge, in der sie empfangen werden, unbestimmt ist.

Mehr Hintergrund zum Deferieren und die verschiedenen Optionen zum verzögerten Laden (deckt den Multi-Defer-Fall nicht ab) Ссылка

Ссылка

Option 2: Verwenden von Statusvariablen

Diese Option kann verwendet werden, wenn einige zusätzliche Zustandsvariablen zu beiden Javascript-Quelldateien hinzugefügt werden können.

Der Ansatz beruht auf einer benannten Variablen in der abhängigen js-Datei und einer benannten Funktion in der js-Datei, die die abhängige Datei verwendet. Wenn die abhängige Datei zu dem Zeitpunkt nicht geladen wird, wenn die Benutzerdatei versucht, auf ihre Funktionalität zuzugreifen, wird sie beendet und wird zurückgerufen, wenn sie wirklich geladen ist.

Dies wird in der folgenden HTML-Datei demonstriert.

Ссылка (funktioniert ordnungsgemäß)

Diese Option funktioniert nicht, wenn das Laden wiederholt durchgeführt werden muss (dh Laden mehrerer Dateien desselben Namens usw.).

Option 3: Nativer Skriptlader

In diesem Fall gibt es mehrere Javascript-Dateien, die Abhängigkeiten voneinander haben.

Es gibt keine Lösung für diesen Fall, bei dem Defender, Async oder andere spezifizierte Tags verwendet werden. Für den Anwendungsfall, den ich in den Remote Labs in gpupowered.org hatte, musste ich meinen eigenen nativen Skriptlader mit XMLHttpRequest implementieren, und die Quelle dafür finden Sie im folgenden Link. Dies verwendet Worker-Threads, da einige der Texturen, die ich habe, ziemlich groß sind. Die Callback-Funktion kann verwendet werden, um die Abhängigkeitslogik gemäß den Anforderungen der Anwendung zu implementieren. Beispiel: Zähle alle geladenen Skripte und trigse dann die vollständige Ausführung usw. an.

Ссылка

Der jquery-Skriptladeprogramm verwendet ebenfalls die HTTP-Anfrage, obwohl ich nicht überprüft habe, ob ein Worker zum Laden verwendet wird. Ссылка

    
prabindh 30.01.2016 11:57
quelle
0
%Vor%     
Autumnswind 02.02.2016 11:41
quelle
0

Verwenden Sie dies:

%Vor%     
Visakh B Sujathan 01.02.2016 11:53
quelle