繁体   English   中英

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

[英]Python Flask - Error: "Failed to load module script. Strict MIME type checking is enforced". Works on production, not on the local server

我有这个 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文件。 在本地(Python 3.7.2)启动Flask web工具时,打开页面时控制台报如下错误:

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

我猜网络服务器(Apache)在生产案例中为它们提供服务,但另一件事是在测试这个 web 工具的其他页面时,它们都可以正常工作并正确加载 javascript 文件(即使它们的内容类型是文本/清楚的)。 然而,我注意到,不同之处在于类型。

这适用于我的情况:

<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 文件)。

谁能帮我解决这个问题?

我在 .js 导出类中遇到了类似的问题,该类包含一个带有集成模板的 vanilla 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 问题,并且大量挖掘都没有结果。 可能需要一个新问题。

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

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

问题是由flask 如何猜测每个静态文件的内容类型引起的。 为此,flask 导入mimetypes并调用mimetype, encoding = mimetypes.guess_type(download_name)

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

在 Linux 和 MacOS 下mimetypes.py查看文件内部:

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
    ]

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

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)

因此,要解决烧瓶认为 .js 文件实际上是text/plain的问题,只需打开 regedit 并将此注册表项调整为application/javascript

注册表编辑器

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

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

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

LK"我

这是另一个无需更改注册表中的任何内容的技巧:
在导入烧瓶之前放这个:

# fix windows registry stuff
import mimetypes
mimetypes.add_type('application/javascript', '.js')
mimetypes.add_type('text/css', '.css')

Harel Ashwal,非常感谢。 由于 mimetype 错误,我无法在 flask 上加载外部 CSS 文件,您分享的这个位为我修复了它:

# fix windows registry stuff
import mimetypes
mimetypes.add_type('application/javascript', '.js')
mimetypes.add_type('text/css', '.css')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM