Python Flask-错误:“无法加载模块脚本。将执行严格的MIME类型检查”。适用于生产环境,而不适用于本地服务器

时间:2019-12-16 10:55:59

标签: javascript python html flask http-headers

我有这个html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link
        rel="stylesheet"
        href="../../../static/css/style.css"
        type="text/css" />
    <link
        rel="stylesheet"
        href="../../../static/css/user_header.css"
        type="text/css" />

    <!--suppress HtmlUnknownTarget -->
    <link rel="shortcut icon" href="/favicon.png">

    <script type="module" src="../../../static/js/node_connect.js" ></script>  <-- Error
    <script src="../../../static/lib/jquery.min.js"></script>
    <script src="../../../static/lib/selfserve.js"></script>   

</head>

有问题的位是node_connect.js文件。在本地启动Flask Web工具(Python 3.7.2)时,打开页面时控制台中会出现以下错误:

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

检查标题:

Content-Type: text/plain; charset=utf-8

但是,在生产中(通过Gunicorn启动时)会给出以下信息:

Content-Type: application/javascript; charset=utf-8

我猜想Web服务器(Apache)在生产案例中为他们提供服务,但是另一件事是,在测试此Web工具的其他页面时,它们都可以正常工作并加载 正确显示javascript文件(即使它们的内容类型是text / plain)。但是,我发现区别是 在类型中。

这对我而言有效:

<script src="../../static/js/translator/library/materialize.js"></script>

或者这个:

<script type="application/javascript" src="../../static/js/translator/library/materialize.js"></script>

当然,我尝试对有问题的javascript文件进行此操作,并收到以下错误(表示现在已加载):

Uncaught SyntaxError: Cannot use import statement outside a module

据我研究,这基本上意味着我需要将类型设置为module(但是这会使浏览器拒绝.js文件)。

有人可以帮我吗?

4 个答案:

答案 0 :(得分:1)

我在.js导出类中遇到了类似的麻烦,该类包含带有集成模板的原始js Web组件,而该模板本身具有jinja2转义序列。 因此,使用url_for的第一个脚本语句可能不会像我一样出现相同的错误。

这似乎正在加载,因为模板引擎未引发任何错误...

<script type="module" src="{{ url_for('static', filename='interval_table.js') }}"></script>

...但是Firefox控制台报告错误:Loading module from “http://127.0.0.1:8000/static/interval_table.js” was blocked because of a disallowed MIME type (“application/json”). https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options

我想通过以下方法解决json错误,但它会导致jinja2错误,无法创建端点:

<script type="module" src="{{ url_for('auth/interval_table.js') }}"></script>

这看起来不像是CORS问题,而且大量挖掘工作都没有结果。可能需要一个新问题。

答案 1 :(得分:1)

问题是由flask 如何猜测每个静态文件的内容类型引起的。 为此,烧瓶导入 mimetypes 并调用 define ratio

此模块从多个来源创建一个已知 mime 类型的数据库,并使用它来返回 mime 类型。

在 Linux 和 MacOS 下,letrec (ratio ...) (r-list ...) 查看文件内部:

mimetype, encoding = mimetypes.guess_type(download_name)

但在 Windows 下,它会在注册表中查找:

mimetypes.py

因此,要解决flask 认为.js 文件实际上是knownfiles = [ "/etc/mime.types", "/etc/httpd/mime.types", # Mac OS X "/etc/httpd/conf/mime.types", # Apache "/etc/apache/mime.types", # Apache 1 "/etc/apache2/mime.types", # Apache 2 "/usr/local/etc/httpd/conf/mime.types", "/usr/local/lib/netscape/mime.types", "/usr/local/etc/httpd/conf/mime.types", # Apache 1.2 "/usr/local/etc/mime.types", # Apache 1.3 ] 的问题,只需打开regedit 并将此注册表项调整为with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, '') as hkcr: for subkeyname in enum_types(hkcr): try: with _winreg.OpenKey(hkcr, subkeyname) as subkey: # Only check file extensions if not subkeyname.startswith("."): continue # raises OSError if no 'Content Type' value mimetype, datatype = _winreg.QueryValueEx( subkey, 'Content Type') if datatype != _winreg.REG_SZ: continue self.add_type(mimetype, subkeyname, strict)

regedit

答案 2 :(得分:0)

您可以使用type="module"属性代替使用defer来达到相同的效果。即:在页面加载完成之前,脚本不会执行。

<script defer src="flong.js"></script>

答案 3 :(得分:0)

我不确定它是否有帮助,但我遇到了类似的问题,通过将模块 js 扩展名从 .js 更改为 .mjs 解决了这个问题。我不认为 Flask 可以看出区别,不像 Node.js,没有不同的扩展。

我知道这是一个旧线程,但我遇到了类似的问题,使用我提到的方法解决了。

我在发帖之前没有看到这个,但我的帖子在这里: Flask Server Not Sending JS Module Script