python - 上传图像时出现“CORS 请求未成功”且 Flask 引发错误(仅限 Firefox)
问题描述
我正在尝试使用我的应用程序调试 CORS 问题。具体来说,它仅在 Firefox 中失败,而且似乎只有在更大的文件中才会失败。
我flask
在后端使用,我正在尝试将“错误”图像上传到我的服务。当我说故障时,我的意思是后端应该拒绝带有 400 的图像(只接受 PNG,不接受 JPG)。上传任何大小的 PNG 都可以。但是,当我拒绝 JPG 文件时,浏览器请求失败,Network error
并且我无法捕获 400 错误来显示用户友好的消息。从后端来看,一切都是一样的,总是返回相同的标头,无论是接受还是拒绝请求,POST
或者OPTIONS
.
但是,我注意到它只会在文件较大时失败。如果我发送几 KB 的 JPG,它可以工作。如果我发送几 MB 的 JPG,它会失败。
我看过一切
curl
-ing 后端提供所有正确的标题- 浏览器没有
OPTIONS
记录任何请求,但如果有,我还检查了那些带有curl
正确标题的请求 - 我只使用 HTTP(不是 HTTPS),所以证书没有问题
- 我已禁用所有扩展程序,因此无法阻止浏览器
- 也许其他我不记得的事情
可能是什么原因?请注意,一切都按预期工作
跨域请求被阻止:同源策略不允许读取位于 http://localhost:8083/api/image 的远程资源。(原因:CORS 请求未成功)。
解决方案
好吧,经过几个小时的试验,这似乎与 CORS 无关。这可能是最令人困惑的错误消息。从Firefox 的文档中引用(强调我的):
使用 CORS 的 HTTP 请求失败,因为 HTTP 连接在网络或协议级别失败。该错误与 CORS 没有直接关系,而是某种基本的网络错误。在许多情况下,它是由浏览器插件(例如广告拦截器或隐私保护器)阻止请求引起的。
因此,这实际上应该表明问题出在后端,尽管它非常微妙。
由于在我的代码中我根据传输的文件名拒绝请求,因此如果名称以.jpg
. 相反,我立即拒绝。这是 Flask 开发服务器的问题,在这种情况下它不会清空输入流(issue here)。
因此,如果您想在保留开发服务器的同时处理这个问题,您应该使用输入。就我而言,我添加了一个自定义错误处理程序,如下所示:
class BadRequestError(ValueError):
"""Raised when a request does not conform to the protocol"""
pass
@app.errorhandler(BadRequestError)
def bad_request_handler(error):
# throw away the request data to avoid closing the connection before receiving all of it
# http://flask.pocoo.org/snippets/47/
_ = request.data
_ = request.form
response = jsonify(str(error))
response.status_code = 400
return response
然后,在代码中,我总是raise BadRequestError('...')
,而不是仅仅返回 400 响应。
推荐阅读
- rust - 如何将结构引用存储在 vec 中并稍后在其他地方使用该结构?
- matlab - 无法满足 fmincon 中的积分容差以解决 ODE 优化问题
- webpack - Webpack 在 css 和 html 中的相对路径错误
- html - 使用 CSS 在另一个容器中居中绝对容器
- android - 试图存储 mutableListOf
到 SharedPreferences 但不能设置默认值 - java - 我可以向 String 类添加新方法吗?
- google-apps-script - 如何使用 Apps 脚本在 google sheet 中提取 pubhtml ID?
- java - 使用 JSTL 在 List 中迭代 Set
- mysql - 如果它大于另一个值,则将值添加到 MySQL 中的行
- python - 如何从 pygresql 中捕获特定异常?