2014-02-20 9 views
19

Ich entwickle eine Bibliothek, die ich auf einem CDN hosten möchte. Die Bibliothek wird in vielen verschiedenen Domänen auf mehreren Servern verwendet. Die Bibliothek selbst enthält ein Skript (nennen wir es jetzt script.js), das einen Web-Arbeiter (worker.js) lädt.Führe Web-Worker aus verschiedenen Quellen aus

Das Laden der Bibliothek selbst ist recht einfach: Fügen Sie einfach das Tag <script type="text/javascript" src="http://cdn.mydomain.com/script.js"></script> zu der Domäne hinzu, auf der ich die Bibliothek verwenden möchte (www.myotherdomain.com). Da die Bibliothek jedoch einen Worker von http://cdn.mydomain.com/worker.jsnew Worker('http://cdn.mydomain.com/worker.js') lädt, erhalte ich eine SecurityException. CORS ist auf cdn.mydomain.com aktiviert.

Für Web-Arbeiter ist es nicht erlaubt, einen Web-Arbeiter in einer Remote-Domäne zu verwenden. Die Verwendung von CORS wird nicht helfen: Browser scheinen es zu ignorieren und führen nicht einmal die Preflight-Prüfung durch.

Ein Weg um dies zu tun wäre, eine XMLHttpRequest durchzuführen, um die Quelle des Arbeiters zu erhalten und dann eine BLOB-URL zu erstellen und einen Arbeiter mit dieser URL zu erstellen. Dies funktioniert für Firefox und Chrome. Dies scheint jedoch nicht für Internet Explorer oder Opera zu funktionieren.

Eine Lösung wäre, den Worker auf www.motherdomain.com zu platzieren oder eine Proxy-Datei zu platzieren (die den Worker einfach mit XHR oder importScripts aus dem cdn lädt). Ich mag diese Lösung jedoch nicht: Ich muss zusätzliche Dateien auf dem Server speichern, und da die Bibliothek auf mehreren Servern verwendet wird, wäre eine Aktualisierung schwierig.

Meine Frage besteht aus zwei parsts:

  1. Ist es möglich, einen Arbeiter auf einem entfernten Ursprung für IE 10+ zu haben?
  2. Wenn 1 der Fall ist, wie wird es am besten gehandhabt, Cross-Browser zu arbeiten?

Antwort

12

Für diejenigen, die diese Frage finden:

YES.

Es ist absolut möglich: Der Trick besteht darin, einen Iframe in der Remote-Domäne zu nutzen und mit ihm über postMessage zu kommunizieren. Der Remote-Iframe (gehostet auf cdn.mydomain.com) kann den Webworker (unter cdn.mydomain.com/worker.js) laden, da beide den gleichen Ursprung haben. Der Iframe kann dann als Proxy zwischen den postMessage-Aufrufen fungieren. Die script.js wird jedoch dafür verantwortlich sein, die Nachrichten zu filtern, so dass nur gültige Worker-Nachrichten behandelt werden.

Der Nachteil ist, dass Kommunikationsgeschwindigkeiten (und Datenübertragungsgeschwindigkeiten) einen Leistungseinbruch nehmen.

Kurz:

  • script.js anhängt iframe mit src="//cdn.mydomain.com/iframe.html"
  • iframe.html auf cdn.mydomain.com/iframe.html führt new Worker("worker.js") und fungiert als Proxy für message Ereignisse aus dem Fenster und worker.postMessage (und umgekehrt).
  • script.js kommuniziert mit dem Worker über iframe.contentWindow.postMessage und das message Ereignis aus dem Fenster. (mit den richtigen Prüfungen für die richtige Herkunft und Arbeiteridentifikation für mehrere Arbeiter)
+3

Oder Sie könnten das Skript selbst hosten und sparen Sie sich all diese Probleme ... – 0xcaff

+1

Sicher, aber das ist nicht möglich, wenn das Skript als Worker für eine Bibliothek geladen wird, die Websites anderer Benutzer zur Verfügung gestellt wird, was der Anwendungsfall für diese Frage war. – MrP