有没有办法为 Starlette/Uvicorn 显式设置 MIME 类型?

Posted

技术标签:

【中文标题】有没有办法为 Starlette/Uvicorn 显式设置 MIME 类型?【英文标题】:Is there a way to explicitly set MIME types for Starlette/Uvicorn? 【发布时间】:2020-06-01 19:49:04 【问题描述】:

似乎我的简单 Starlette/Uvicorn Web 应用程序为 Jinja 模板化(从同一服务器提供)javascript 文件提供了不正确的 MIME 内容类型。从屏幕截图中可以看出,uvicorn 服务器正在将 *.js 文件转换为类型(“text/plain”)。

Screenshot

我已经搜索了 Starlette 和 Uvicorn 的文件,只是被难住了。

我的简单网络应用如下:

from starlette.applications import Starlette
from starlette.staticfiles import StaticFiles
from starlette.responses import htmlResponse
from starlette.templating import Jinja2Templates
from starlette.middleware.cors import CORSMiddleware
import uvicorn
from random import randint

port = randint(49152,65535)

templates = Jinja2Templates(directory='templates')


app = Starlette(debug=True)
app.mount('/static', StaticFiles(directory='statics', html=True), name='static')
app.add_middleware(
    CORSMiddleware, allow_origins=["*"], allow_headers=["*"], allow_methods=["*"]
)

@app.route('/')
async def homepage(request):
    template = "index.html"
    context = "request": request
    return templates.TemplateResponse(template, context, media_type='text/html')


@app.route('/error')
async def error(request):
    """
    An example error. Switch the `debug` setting to see either tracebacks or 500 pages.
    """
    raise RuntimeError("Oh no")


@app.exception_handler(404)
async def not_found(request, exc):
    """
    Return an HTTP 404 page.
    """
    template = "404.html"
    context = "request": request
    return templates.TemplateResponse(template, context, status_code=404)


@app.exception_handler(500)
async def server_error(request, exc):
    """
    Return an HTTP 500 page.
    """
    template = "500.html"
    context = "request": request
    return templates.TemplateResponse(template, context, status_code=500)


if __name__ == "__main__":
    uvicorn.run("app-567:app", host='0.0.0.0', port=port, log_level="info", http='h11', loop='asyncio', reload=True)

在头部加载的 JavaScript 文件给出了相同的错误,但仍然加载。这是 Firefox(73.0 64 位)中新的“nosniff”默认设置的副产品。作为模块导入加载的脚本完全失败。

我正在运行 Windows 10 (x64)、Python 3.7、uvicorn 0.11.2 和 starlette 0.13.1。

非常感谢任何帮助。 提前谢谢你。

【问题讨论】:

我可以通过如下显式设置 mimetypes 变量来解决此问题: 【参考方案1】:

我能够通过如下显式设置 mimetypes 变量来解决此问题:

from starlette.applications import Starlette
from starlette.staticfiles import StaticFiles
from starlette.responses import HTMLResponse
from starlette.templating import Jinja2Templates
from starlette.middleware.cors import CORSMiddleware
import uvicorn
from random import randint

import mimetypes
mimetypes.init()

port = randint(49152,65535)

templates = Jinja2Templates(directory='templates')


app = Starlette(debug=True)
app.mount('/static', StaticFiles(directory='statics', html=True), name='static')
app.add_middleware(
    CORSMiddleware, allow_origins=["*"], allow_headers=["*"], allow_methods=["*"]
)

@app.route('/')
async def homepage(request):
    mimetypes.add_type('application/javascript', '.js')
    mimetypes.add_type('text/css', '.css')
    mimetypes.add_type('image/svg+xml', '.svg')
    template = "index.html"
    context = "request": request
    return templates.TemplateResponse(template, context, media_type='text/html')


@app.route('/error')
async def error(request):
    """
    An example error. Switch the `debug` setting to see either tracebacks or 500 pages.
    """
    raise RuntimeError("Oh no")


@app.exception_handler(404)
async def not_found(request, exc):
    """
    Return an HTTP 404 page.
    """
    template = "404.html"
    context = "request": request
    return templates.TemplateResponse(template, context, status_code=404)


@app.exception_handler(500)
async def server_error(request, exc):
    """
    Return an HTTP 500 page.
    """
    template = "500.html"
    context = "request": request
    return templates.TemplateResponse(template, context, status_code=500)


if __name__ == "__main__":
    uvicorn.run("app-567:app", host='0.0.0.0', port=port, log_level="info", http='h11', loop='asyncio', reload=True)

【讨论】:

酷!不知道您可以通过这种方式添加 mimetypes 关联。谢谢。我有一个类似的问题,我正在动态生成 .js 文件,最后在 super().__init__ 中使用 media_type 的“application/javascript”子类化 Reponse,就像你得到的一样。 是的!可以确认添加 mimetypes 也为我解决了 svg 渲染问题。

以上是关于有没有办法为 Starlette/Uvicorn 显式设置 MIME 类型?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法为故事书提供“主文件”?

有没有办法将数字单词转换为整数?

有没有办法检查变量是不是为整数? C++

有没有办法将 QTableView 模型转换为 QStandardItemModel

有没有办法为android生成用户ID?

有没有办法为 TextBox 实现 Redo() 函数? C#