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

14
当我尝试运行一个非常简单的本地节点服务器时(请参见下面的代码),我会收到以下错误消息:
从“http://localhost:8080/importing.js”加载模块被阻止,因为 MIME 类型不允许(“text/html”)。
我对Node和ES6模块都很陌生,所以我不太了解问题的细节。根据这个URL,必须明确为模块提供mime-type“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
2个回答

12
基本上,您有一个服务器,对于任何给定的请求,它都会提供您的index.html文件的内容 - 不管该请求看起来像什么。因此,浏览器接收到HTML并开始解释它,为script标签的src发出另一个请求,由于服务器仅提供您的index.html文件,当浏览器期望JavaScript时,浏览器第二次收到HTML文件。
通常,您首先创建一个服务器,然后根据输入的请求构建响应。如下是一个原始示例,展示了如何按照您预期的方式提供静态文件:
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)

请注意,这个例子过于信任客户端,通常需要以某种方式对请求进行净化处理。我坚持使用了普通的JavaScript,但是一旦您熟悉其工作原理,值得尝试查看一下Express,因为它可以简化路由/ MIME类型样板文件等。


我已经创建了一个Express服务器。但是我无法通过这个解决方案解决MIME错误。这是我的[server.js] 1,这是我的[api.js] 2 - Tanzeel
我运行了API和Angular构建,看起来符合预期。这似乎是您的服务器/环境出现了问题,但没有足够的信息来重现该问题。无论如何,最好将此作为单独的SO问题进行处理,并使用MCVE - Emissary
好的,我明白了。但是我已经在 https://dev59.com/c1MH5IYBdhLWcg3w0DO9 和 https://stackoverflow.com/questions/57978442/getting-mime-type-errors-with-mean-stack-project-while-deploying-it 上提问了。请帮帮我。 - Tanzeel
请参见 https://stackoverflow.com/questions/58254370/how-to-send-headers-in-express-mean 了解有关在Express中发送标头的信息。谢谢。 - Tanzeel

0

我知道你只是导入了命令,但我想让你知道我的解决方案,看看你是否感兴趣。对我来说,这个错误来自于你模块中的导入语句。我试图导入整个文件,包括它所拥有的所有函数和导入,而实际上使用的是同一个服务器和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显然不喜欢给任何导入它的文件访问其函数或变量的权限,除非手动将其附加到窗口。你现在没有这个错误,但是在文件成功导入后,它会告诉你a未定义。虽然我已经将它附加到我的importing.js函数中,但你需要像这样将它放在exporting.js中:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接