html Python flask -错误:“无法加载模块脚本,强制执行严格的MIME类型检查”,在生产环境中工作,不在本地服务器上工作

ef1yzkbh  于 2023-01-28  发布在  Python
关注(0)|答案(6)|浏览(170)

我有这个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文件)。
有人能帮我一下吗?

ruoxqz4g

ruoxqz4g1#

问题是由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)

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

7xllpg7q

7xllpg7q2#

LK“I
这里有另一个技巧,而不需要改变注册表中的任何东西:
在导入 flask 前放置此:

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

rbpvctlc3#

我在一个.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问题,大量的挖掘没有产生任何结果。一个新的问题可能是必要的。

ycggw6v2

ycggw6v24#

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

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

kupeojn65#

我不确定这是否有帮助,但我有一个类似的问题,它是通过将模块js扩展名从.js改为. mjs解决的。我不认为Flask可以看到不同之处,不像Node.js,没有不同的扩展名。
我知道这是一个老线索,但我有一个类似的问题,是用我提到的方法解决的。
我没有看到这个之前,我张贴,但我的线程在这里:Flask Server Not Sending JS Module Script

hjzp0vay

hjzp0vay6#

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

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

相关问题