节点服务器:由于不允许的 MIME 类型(“text/html”),加载模块被阻止

Node server: Loading module was blocked because of a disallowed MIME type (“text/html”)

当我尝试使用非常简单的应用程序 运行 本地节点服务器时收到以下错误消息(请参阅下面的编码)。

由于不允许的 MIME 类型(“text/html”),从“http://localhost:8080/importing.js”加载模块被阻止。

我是 node 和 ES6 模块的新手,所以我不太了解问题的细节。根据这个 URL mime 类型 'application/javascript' 必须明确地为模块提供服务。但是我如何在下面的示例中实现这一点?

index.html

<!DOCTYPE html>
<html>
  <head>
    <script src="./importing.js" type="module"></script>
    <meta charset="utf-8">
  </head>
  <body>
  </body>
</html>

server.js

var http = require('http');
var fs = require('fs');

const PORT=8080;

fs.readFile('./index.html', function (err, html) {

    if (err) throw err;

    http.createServer(function(request, response) {
        response.writeHeader(200, {"Content-Type": "text/html"});
        response.write(html);
        response.end();
    }).listen(PORT);
});

importing.js

import {a} from './exporting.js';

console.log(a);

exporting.js

export const a = 'Constant a';

我在 CMD 中使用

启动服务器
node server.js

本质上,您有一个服务器可以为任何给定的请求提供您的 index.html 文件的内容 - 无论该请求看起来像什么。因此,浏览器接收到 HTML 并开始解释它,对你的 script 标签的 src 发出另一个请求,由于服务器只提供你的 index.html 文件,浏览器收到您的 HTML 文件在预期 javascript.

时第二次提交

通常您会先创建一个服务器,然后根据作为输入的请求构建响应。按照您的预期提供静态文件的原始示例可能如下所示:

const http = require('http')
const fs = require('fs')

const PORT = 8080

http
    .createServer((request, response) => {
        fs.readFile(`.${request.url}`, (err, data) => {
            if (err) {
                response.writeHeader(404, {
                    'Content-Type': 'text/plain'
                })
                response.write('404 Not Found')
                response.end()
                return
            }

            if (request.url.endsWith('.html')) {
                response.writeHeader(200, {
                    'Content-Type': 'text/html'
                })
            }

            if (request.url.endsWith('.js')) {
                response.writeHeader(200, {
                    'Content-Type': 'application/javascript'
                })
            }

            response.write(data)
            response.end()
        })
    })
    .listen(PORT)

请注意,此示例过于信任客户端,您通常希望以某种方式清理请求。我一直使用 vanilla javascript,但是一旦您对它的工作方式感到满意,就值得一试 Express,因为它将简化路由/mime 类型样板等

我知道您只是导入命令,但我会让您知道我的解决方案,看看您是否感兴趣。对我来说,这个错误来自模块中的 import 语句。我试图导入整个文件,包括它的所有功能和导入,同时基本上使用相同的服务器和 HTML.

我的importing.js:

import * as Spotify from "./spotify-web-api.js";

window.basicAlert = function basicAlert() {
    alert("this is a test to see if basicAlert runs properly");
}

console.log("Should print to console with no error on imports");

我不知道 import * as 背后的逻辑,但它成功导入了我的文件而没有引发 MIME 类型错误。至于 window.basicAlert =,Javascript 显然不想让任何导入它的文件访问它的函数或变量,除非它被手动附加到 window。你现在没有这个错误,但是文件导入成功后它会告诉你 a 未定义。虽然我将它附加到 importing.js 中的函数,但您需要像这样将它放在 exporting.js 中:

const a = 'Constant a';
windows.a = a;

我没有测试 ^ 但它对我来说很有意义。我希望这可以帮助你,或者更接近,因为它解决了我的问题。