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 fo
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
I solved the same problem adding this line to apache mime types file configuration:
AddType aplication/javascript .js
I hope this helps.
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';
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>
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.
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.