我有一个基本的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的问题,但这是一个简单的解决方法,可以立即修复。