有没有办法为 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 类型?的主要内容,如果未能解决你的问题,请参考以下文章