web-dev-qa-db-ja.com

ローカルファイルのES6モジュール-サーバーは非JavaScript MIMEタイプで応答しました

私はこのエラーを受け取ります:

モジュールスクリプトの読み込みに失敗しました:サーバーはJavaScript以外のMIMEタイプ ""で応答しました。 HTML仕様ごとにモジュールスクリプトに対して厳密なMIMEタイプチェックが実施されます。

プロジェクトはローカルファイルから実行されます。例:file:///D:/path/project.html

Firefoxでは問題なく動作しますが、Google Chromeでは動作しません。開発目的でこの方法でテストしたい-サーバーを作成して、どのポートにあるかを覚えるよりも快適です。

26
Tomáš Zato

このエラーメッセージが表示された場合、Same-Originの問題ではないことを意味します。

エラーメッセージで述べたように、実際の問題は、モジュールスクリプトがスクリプトファイルのMIMEをjavascript MIMEタイプの1つにする必要があることです。

ファイルシステムはMIMEを提供しないため、読み込みは失敗します。

したがって、最善の解決策は、ファイルシステムではなくローカルサーバーでコードを実行することです。

しかし、あなたは主張しているので;)1つの回避策は、最初にXHRを使用してスクリプトファイルをBlobとしてフェッチすることです(fetchは使用できませんfile://プロトコル)、次にそのtypeプロパティをjs MIMEの1つに設定し、<script>のsrcをこのBlobを指すblobURIに設定します。

// 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、モジュール内からimport依存関係を作成することはできません。

7
Kaiido

ここにリストされていない私の簡単な修正はこれでした:

別のファイルからオブジェクトを取得するimportステートメントがありましたが、これは次の行で行いました。

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

コードを壊し、MIMEタイプエラーを引き起こしたのは、.jsの最後に./modules/Cellが追加されていなかったことです。

更新された行は私の問題を修正しました:

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

16
Jay Gould

ModuleSpecifierdata URIに設定できます

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

プログラムでModuleSpecifierを設定するには、--allow-file-access-from-filesフラグを使用してChromium/Chromeを起動し、XMLHttpRequest()を使用してfile:プロトコルからJavaScriptファイルを要求できます。

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

ES6モジュールファイルは 標準のSame-Originポリシー を使用して読み込まれますセキュリティ標準は、時間の経過とともにブラウザに追加されてきました。それらの1つをヒットしています。つまり、ファイルは正しいMIMEタイプで送信する必要があります。

file:// URLは通常のHTTPリクエストではないため、リクエストに関するルールが異なります。また、送信するMIMEタイプについてのルールもほとんどありません。 ES6モジュールを使用する場合は、ファイルを提供するために実際のHTTPサーバーをローカルで実行する必要があります。

2
loganfsmyth

Windowsでは、ES 2016モジュールを正しくロードできません。セキュリティを無効にしても、.jsファイルにはMIMEタイプが設定されていないという次の問題に見舞われます。そのため、「モジュールスクリプトをロードできませんでした」などのメッセージが表示されます。 「」のタイプ。 HTML仕様ごとにモジュールスクリプトに対して厳密なMIMEタイプチェックが実施されます。

答えは、MacintoshでSafariを使用することです。これにより、ES 2016モジュールでローカルファイルを問題なく使用できます。興味深いことに、ChromeとFirefoxの両方も正常に動作しません。率直に言って、これはバグです。なぜなら、ローカルファイルをロードするとき、同じフォルダからファイルにアクセスすることに関して安全性は絶対にないからです。ただし、GoogleまたはFirefoxでこれを修正していただければ幸いです。 Appleのプルダウンメニューには、クロススクリプトのアクセス許可に関するフラグも設定されているため、ナンセンスなセキュリティ機能を無効にすることがいかに重要かがわかります。

0
Edward De Jong