ES6 modules in local files - The server responded with a non-JavaScript MIME type

JavascriptGoogle ChromeEcmascript 6

Javascript Problem Overview


I get this error:

> Failed to load module script: The server responded with a non-JavaScript MIME type of "". Strict MIME type checking is enforced for module scripts per HTML spec.

The project is run from local files, eg.: file:///D:/path/project.html.

Works without problems in Firefox, but doesn't work in Google Chrome. I want to test it this way for development purposes - it's more comfortable than creating a server and remembering what port is it on.

Javascript Solutions


Solution 1 - Javascript

A simple fix for me that wasn't listed here was this:

I had an import statement bringing an object from a different file, which I did via this line:

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

What broke the code and caused the MIME type error was not having .js appended to the end of ./modules/Cell.

The updated line fixed my problem:

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

Solution 2 - Javascript

If you got onto this error message, it means that it's not a Same-origin issue.

As said in the error message, the real problem is that modules scripts require the MIME of your script file to be one of the javascript MIME types.

Your filesystem doesn't provide any MIME, hence the loading fails.

So the best solution is obviously to run your code on a local server, and not on the filesystem.

But since you do insist ;) One workaround is to first fetch your script file as Blob using XHR (fetch can't be used on file:// protocol), then force its type property to be one of js MIMEs, and set your <script>'s src to a blobURI poiting to this 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();

BUT, you won't be able to import any dependencies from within your module.

Solution 3 - Javascript

ES6 module files are loaded using the standard Same-Origin policy restrictions that browsers enforce and have many other security restrictions in place, while JavaScript "script" files have much more lax security to avoid breaking existing websites as better security standards have been added to browsers over time. You are hitting one of them, which is that files must be sent with the correct MIME type.

file:// URLs are not normal HTTP requests, and as such they have different rules around requests. There's also pretty much no rules for what MIME type should be sent. If you want to use ES6 modules then you need to be running a real HTTP server locally to serve your files.

Solution 4 - Javascript

On Windows, i cannot get ES 2016 modules to load correctly. Even if you disable security, then you get hit by the next prolem which is the .js files don't have a MIME type set, so you get a message like Failed to load module script: The server responded with a non-JavaScript MIME type of "". Strict MIME type checking is enforced for module scripts per HTML spec.

The answer is to use Safari on the macintosh, which allows local files no problem with ES 2016 modules. Interestingly both Chrome and Firefox also fail to work properly. Frankly this is a bug, because when you are loading a local file, there is absolutely nothing insecure about accessing files from the same folder. But good luck getting Google or Firefox to fix this. Apple even has a flag about cross-scripting permissions in their pulldown menu, so they know how important it is to disable nonsense security stuff.

Solution 5 - Javascript

You can set the ModuleSpecifier to a data URI

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

to set the ModuleSpecifier programmatically you can launch Chromium/Chrome with --allow-file-access-from-files flag and utilize XMLHttpRequest() to request a JavaScript file from file: protocol

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

Solution 6 - Javascript

I solved the same problem adding this line to apache mime types file configuration:

AddType aplication/javascript .js

I hope this helps.

Solution 7 - Javascript

If the files don't end up with ".js" but ".mjs" try changing them to ".js"

And also if you didn't specify the file type, specify it: ./modules/Cell to ./modules/Cell.js

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTom&#225;š Zato - Reinstate MonicaView Question on Stackoverflow
Solution 1 - JavascriptJames GouldView Answer on Stackoverflow
Solution 2 - JavascriptKaiidoView Answer on Stackoverflow
Solution 3 - JavascriptloganfsmythView Answer on Stackoverflow
Solution 4 - JavascriptEdward De JongView Answer on Stackoverflow
Solution 5 - Javascriptguest271314View Answer on Stackoverflow
Solution 6 - JavascriptFederico AlemanyView Answer on Stackoverflow
Solution 7 - JavascriptPoussyView Answer on Stackoverflow