由于使用HTTP而不是HTTPS,Chrome阻止使用FileResponse下载FastAPI文件



我有一个基本的FastAPI网站,它有一个下载Excel模板的端点。url的方案是HTTPS。直到最近,这在Chrome和Safari上运行良好。随着人们的升级,Chrome一直在阻止下载。这似乎与谷歌针对"混合内容下载"实施的不安全内容政策一致:

https://blog.chromium.org/2020/02/protecting-users-from-insecure.html

我的终点很简单:

@router.get('/download_data_template')
def download_data_template(request: Request):
'''Returns data template from library
'''
# ### auth
# page access is authorized here
# end auth
file_name = 'TEMPLATE schedule_input.xlsx'
return FileResponse(
path=db.get_library_path(file_name),
filename=file_name,
media_type='application/octet-stream',
)

端点是从Jinja2模板化的html页面调用的,其中包含以下内容:

<a class="btn btn-primary" href="{{ url_for('upload_schedule')}}" data-toggle="tooltip" data-delay='{"show":750, "hide":250}' data-placement="top" data-toggle="tooltip" data-delay='{"show":750, "hide":250}' data-placement="top" title="click to select and upload file. The file must be in property format.">upload schedule input workbook</a>

在Chrome上,开发者面板显示以下错误:

"Mixed Content: The site at 'https://<my_url>.com/' was loaded over a secure connection, but the file at 'https://<my_url>.com/download_data_template' was redirected through an insecure connection. This file should be served over HTTPS. This download has been blocked. See https://blog.chromium.org/2020/02/protecting-users-from-insecure.html for more details."

这个文件并不是唯一的,它是一个基本的Excel.xlsx文件,一个供人们填写的模板。

这在Safari和Edge中仍然运行良好,但被Chrome阻止。

chromium博客中的文章内容丰富,但我不知道如何确保下载的安全。我也找过,但没有成功。

关于如何使用符合谷歌新政策的FastAPI从光盘下载基本文件,特别是.xlsx文件,有什么想法吗?

谢谢你在这方面的帮助。

选项1

您可以使用HTTPSRedirectMiddleware强制将所有传入到http的请求重定向到安全方案。

from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI()
app.add_middleware(HTTPSRedirectMiddleware)

选项2

除上述内容外,您还可以使用相对URL,而不是在Jinja2模板中使用url_for();例如:

<a href="/upload_schedule">Link text</a>

这样,URL的方案将保持为https

选项3

您可以使用自己的url_for自定义函数来替换URL的方案,类似于本答案选项2中演示的方法。


如果您在代理服务器(如Nginx(后面,您也可以尝试将--proxy-headers参数传递给Uvicorn,如下所述。

我正在通过FastAPI后端开发React应用程序,遇到了类似的问题。我不确定{{ url_for('upload_schedule')}}在渲染引擎中的评估结果,但在我的情况下,问题在于URL不准确以及FastAPI对其的处理。

参考您的示例,我在UI中放置了代码/download_data_template/,因此FastAPI引擎发送了307,因为它重定向到了/download_data_template。在UI代码中用/download_data_template替换/download_data_template/为我解决了这个问题。

这可能是Chrome的问题,而不是FastAPI的问题,但这是一个简单的解决方法,可以立即修复。

最新更新