it-swarm.com.de

ES6-Module in lokalen Dateien - Der Server hat mit einem Nicht-JavaScript-MIME-Typ geantwortet

Ich erhalte diesen Fehler:

Laden des Modulskripts fehlgeschlagen: Der Server hat mit dem Nicht-JavaScript-MIME-Typ "" geantwortet. Die strikte Überprüfung des MIME-Typs wird für die Modulskripts pro HTML-Spezifikation erzwungen.

Das Projekt wird aus lokalen Dateien ausgeführt, zB: file:///D:/path/project.html.

Funktioniert ohne Probleme in Firefox, aber nicht in Google Chrome. Ich möchte es auf diese Weise zu Entwicklungszwecken testen - es ist komfortabler, als einen Server zu erstellen und sich zu erinnern, an welchem ​​Port er sich befindet.

16
Tomáš Zato

Wenn Sie diese Fehlermeldung erhalten haben, bedeutet dies, dass es sich nicht um ein Same-Origin-Problem handelt.

Wie in der Fehlermeldung angegeben, besteht das eigentliche Problem darin, dass für die Skripts der Module der MIME Ihrer Skriptdatei einer der Javascript-MIME-Typen sein muss.

Ihr Dateisystem stellt kein MIME bereit, daher schlägt das Laden fehl.

Die beste Lösung ist also, Ihren Code auf einem lokalen Server auszuführen und nicht auf dem Dateisystem.

Aber da Sie darauf bestehen;) Eine Abhilfemaßnahme besteht darin, Ihre Skriptdatei zunächst als Blob mit XHR abzurufen (fetch kann nicht für das file://-Protokoll verwendet werden), dann erzwingen Sie, dass die type-Eigenschaft eine der js-MIMEs ist, und setzen Sie diese Eigenschaft Ihr <script>s src zu einem BlobURI, der auf diesen Blob verweist.

// requires to start chrome with the --allow-file-access-from-file flag
var xhr = new XMLHttpRequest();
xhr.onload = e => {
    let blob = xhr.response;
    blob.type = 'application/javascript'; // force the MIME
    moduleScript.src = URL.createObjectURL(blob);
};
xhr.open('get', "yourmodule.js");
xhr.responseType = 'blob';
xhr.send();

, ABER, Sie können keine Abhängigkeiten aus Ihrem Modul import.

5
Kaiido

Eine einfache Lösung für mich, die hier nicht aufgeführt wurde, war folgende:

Ich hatte eine Import-Anweisung, die ein Objekt aus einer anderen Datei brachte, und zwar über diese Zeile:

import { Cell } from './modules/Cell';

Was den Code gebrochen hat und den MIME-Typ-Fehler verursacht hat, wurde .js nicht am Ende von ./modules/Cell angehängt. 

Die aktualisierte Zeile hat mein Problem behoben:

import { Cell } from './modules/Cell.js';

11
Jay Gould

ES6-Moduldateien werden unter Verwendung der standard Same-Origin-Richtlinien -Einschränkungen geladen, die Browser durchsetzen, und viele andere Sicherheitsbeschränkungen haben, während JavaScript- "Skript" -Dateien viel laschere Sicherheit aufweisen, um zu verhindern, dass bestehende Websites mit besseren Sicherheitsstandards beschädigt werden wurde im Laufe der Zeit zu Browsern hinzugefügt. Sie treffen eine davon, das heißt, dass Dateien mit dem richtigen MIME-Typ gesendet werden müssen.

file://-URLs sind keine normalen HTTP-Anforderungen und daher gelten für sie andere Regeln. Es gibt auch so gut wie keine Regeln, an welchen MIME-Typ gesendet werden soll. Wenn Sie ES6-Module verwenden möchten, müssen Sie einen lokalen HTTP-Server lokal ausführen, um Ihre Dateien bereitzustellen.

3
loganfsmyth

Sie können die ModuleSpecifier auf einen data URI setzen.

<script type="module">
  import {Test} from "data:application/javascript,const%20Mod={this.abc=123};export%20{Mod};";
  console.log(Test);
</script>

um ModuleSpecifier programmgesteuert festzulegen, können Sie Chromium/Chrome mit dem Code --allow-file-access-from-files starten und mit XMLHttpRequest() eine JavaScript-Datei vom Protokoll file: anfordern

<script>
(async() => {

  const requestModule = ({url, dataURL = true}) => 
    new Promise((resolve, reject) => {
      const request = new XMLHttpRequest();
      const reader = new FileReader();
      reader.onload = () => { resolve(reader.result) };
      request.open("GET", url);
      request.responseType = "blob";
      request.onload = () => { reader[dataURL ? "readAsDataURL" : "readAsText"](request.response) };
      request.send();
   })

  let moduleName = `Mod`;
  // get `Mod` module
  let moduleRequest = await requestModule({url:"exports.js"});
  // do stuff with `Mod`; e.g., `console.log(Mod)`
  let moduleBody = await requestModule({url:"ModBody.js", dataURL: false}); 
  let scriptModule = `import {${moduleName}} from "${moduleRequest}"; ${moduleBody}`;
  let script = document.createElement("script");
  script.type = "module";
  script.textContent = scriptModule;
  document.body.appendChild(script);

})();
</script>
1
guest271314

Unter Windows können ES 2016-Module nicht ordnungsgemäß geladen werden. Selbst wenn Sie die Sicherheit deaktivieren, werden Sie vom nächsten Prolem getroffen, bei dem es sich um JS-Dateien handelt, für die kein MIME-Typ festgelegt ist. Sie erhalten daher die Meldung Fehler beim Laden des Modulskripts: Der Server hat mit einem Nicht-JavaScript-MIME geantwortet Art der "". Die strikte MIME-Typprüfung wird für Modulskripten gemäß HTML-Spezifikation erzwungen.

Die Antwort ist, Safari auf dem Macintosh zu verwenden, wodurch lokale Dateien mit ES 2016-Modulen kein Problem darstellen. Interessanterweise funktionieren sowohl Chrome als auch Firefox nicht richtig. Ehrlich gesagt ist dies ein Fehler, denn wenn Sie eine lokale Datei laden, ist der Zugriff auf Dateien aus demselben Ordner absolut nicht unsicher. Aber gut Glück, dass Google oder Firefox dieses Problem beheben. Apple hat sogar eine Markierung für Cross-Scripting-Berechtigungen im Pulldown-Menü, sodass sie wissen, wie wichtig es ist, unsinniges Sicherheitsmaterial zu deaktivieren.

0
Edward De Jong