61 votes

Modules ES6 dans les fichiers locaux - Le serveur a répondu avec un type MIME non-JavaScript

Je reçois cette erreur :

Impossible de charger le module script : le serveur a répondu avec un type MIME non-JavaScript de "". La vérification stricte du type MIME est appliquée pour le module script par la spécification HTML.

Le projet est exécuté à partir de fichiers locaux, par exemple.. : file:///D:/path/project.html .

Fonctionne sans problème dans Firefox, mais ne fonctionne pas dans Google Chrome. Je veux le tester de cette façon à des fins de développement - c'est plus confortable que de créer un serveur et de se souvenir du port sur lequel il se trouve.

1 votes

Vous devez configurer un serveur HTTP local. Utiliser des fichiers : URL n'est jamais une bonne idée car elle ne se comporte pas comme une véritable page.

3 votes

Les utilisateurs finaux reçoivent la page emballée avec webpack. Mais pour moi, il est plus confortable de tester avec des fichiers. Je peux lancer un serveur python ou node.js, mais je n'en ai pas envie.

1 votes

En fait, je viens d'essayer et vous n'êtes pas confronté à cette restriction de même origine. C'est comme le dit le message d'erreur : ils font une vérification stricte contre le type MIME js, votre système de fichiers n'en fournit pas.

55voto

Jay Gould Points 1655

Une solution simple pour moi, qui n'était pas mentionnée ici, était la suivante :

J'avais une déclaration d'importation amenant un objet depuis un fichier différent, ce que j'ai fait via cette ligne :

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

Ce qui a cassé le code et causé l'erreur de type MIME était de ne pas avoir .js ajouté à la fin de ./modules/Cell .

La ligne mise à jour a réglé mon problème :

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

0 votes

Wow. Yup. Juste ici. C'est logique, aussi, parce que cela indique explicitement le type du module d'importation.

1 votes

Jona : Oui, c'est logique avec le recul, mais je devenais folle à force de chercher à comprendre.

1 votes

Haha Je suis content que tu l'aies trouvé avant que je tombe sur le même problème :p

23voto

Kaiido Points 35595

Si vous êtes tombé sur ce message d'erreur, cela signifie qu'il ne s'agit pas d'un problème d'origine identique.

Comme indiqué dans le message d'erreur, le vrai problème est que les modules scripts exigent que le MIME de votre fichier scripts soit un des types MIME de javascript.

Votre système de fichiers ne fournit pas de MIME, d'où l'échec du chargement.

La meilleure solution est donc évidemment d'exécuter votre code sur un serveur local, et non sur le système de fichiers.

Mais puisque vous insistez ;) Une solution de contournement consiste à récupérer d'abord votre fichier script en tant que Blob en utilisant XHR ( fetch ne peut pas être utilisé sur file:// ), puis de forcer son type pour qu'elle soit l'un des js MIME, et définissez votre propriété <script> Le src de l'utilisateur est un blobURI lié à ce Blob.

// 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();

MAIS vous ne serez pas en mesure de import toutes les dépendances de votre module.

4 votes

Cela n'aide pas vraiment mais bravo pour la solution de rechange. Cela peut s'avérer utile dans d'autres situations...

1 votes

@TomášZato notez que cela pourrait être possible par le biais de chrome scripts (extension) pour forcer le MIME dans de tels cas, en utilisant l'extension API webRequest mais je ne le connais pas assez pour montrer exactement comment procéder...

4 votes

Et si vous exécutez ce programme sur un serveur local et que vous rencontrez toujours ce problème ?

7voto

loganfsmyth Points 25483

Les fichiers de modules ES6 sont chargés à l'aide de l'option politique standard de la même origine Les fichiers JavaScript "script" bénéficient d'une sécurité beaucoup plus souple pour éviter de casser les sites Web existants, car de meilleures normes de sécurité ont été ajoutées aux navigateurs au fil du temps. Vous vous heurtez à l'une d'entre elles, à savoir que les fichiers doivent être envoyés avec le type MIME correct.

file:// Les URL ne sont pas des requêtes HTTP normales, et en tant que telles, elles sont soumises à des règles différentes. Il n'y a pas non plus de règles concernant le type MIME à envoyer. Si vous voulez utiliser les modules ES6, vous devez faire tourner un vrai serveur HTTP localement pour servir vos fichiers.

3 votes

Je m'interrogeais sur les drapeaux/options de développement possibles pour me permettre de tester les fichiers sans serveur.

1 votes

Je ne crois pas que vous ayez d'autre choix que de faire tourner un serveur.

2 votes

J'utilise le serveur SimpleHTTPS de Python. Pourquoi cela ne suffit-il pas ?

6voto

Edward De Jong Points 26

Sous Windows, je n'arrive pas à charger correctement les modules ES 2016. Même si vous désactivez la sécurité, le problème suivant se pose : les fichiers .js n'ont pas de type MIME défini et vous obtenez un message du type Failed to load module script : The server replied with a non-JavaScript MIME type of "". La vérification stricte du type MIME est appliquée pour le module script par la spécification HTML.

La réponse est d'utiliser Safari sur le macintosh, qui autorise les fichiers locaux sans problème avec les modules ES 2016. Il est intéressant de noter que Chrome et Firefox ne fonctionnent pas non plus correctement. Franchement, il s'agit d'un bug, car lorsque vous chargez un fichier local, il n'y a absolument rien d'insécurisant à accéder à des fichiers du même dossier. Mais bonne chance pour que Google ou Firefox corrigent ce problème. Apple a même un drapeau sur les autorisations de cross-scripting dans son menu déroulant, donc ils savent combien il est important de désactiver les trucs de sécurité absurdes.

3voto

guest271314 Points 2718

Vous pouvez régler le ModuleSpecifier à un data URI

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

pour définir le ModuleSpecifier de manière programmatique, vous pouvez lancer Chromium/Chrome avec --allow-file-access-from-files et utiliser le drapeau XMLHttpRequest() pour demander un fichier JavaScript à file: protocole

<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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X