S3 导入的图像偶尔会损坏:在 Chrome 上呈现,但不是 Firefox

S3-imported images occasionally corrupted: renders on Chrome, but not Firefox

我们应用程序的一部分涉及将远程图像重新托管到我们自己的 S3 存储桶并在我们的网站上显示结果。偶尔在大约 3% 的情况下,图像导入会导致 Firefox 认为图像已损坏,从而导致控制台出现 Image corrupt or truncated. 错误。但是图像在 Chrome 中呈现得非常好, 除非在打印页面对话框中 ,然后它表现出与 Firefox 相同的行为。它似乎在所有情况下都适用于 Safari。

当我将同一个文件重新导入到 S3 甚至另一个托管站点(如 imgur.com)时,问题仍然存在。我创建了一个 fiddle,您可以在其中使用已知损坏的图像自行测试加载行为。

https://jsfiddle.net/ysLa27bo/1/

s3 = Aws::S3::Resource.new(region: 'us-west-1')
obj = s3.bucket(MY_BUCKET_NAME).object(MY_S3_DIR_PATH)
obj.put(body: open(REMOTE_PATH_TO_IMAGE), acl: 'public-read')

以上是我在 Rails 5+ 环境中通过 Sidekiq worker 使用 AWS-SDK-S3 ruby gem 运行 的 S3 导入代码。我应该强调这个损坏的图像问题是间歇性的;我 97% 的其他导入在所有浏览器和设置中都运行良好,所以我认为这不是我的代码的问题。

我最好的猜测是图像在两个步骤之一损坏:在 open()(读取远程图像 url)或我们导入到 S3 的部分。由于图像可以在 Chrome 中完美加载,我认为在后面的步骤中更有可能出现问题。 Sidekiq 是否有可能因应用程序 deploy/restart (Heroku) 而关闭,可能会以某种方式破坏文件导入?只是猜测。

我的问题是:为什么会这样?如何确保在导入到 S3 时不会发生图像损坏?有什么方法可以让我自动检查图像的有效性 post-import,缺少 运行 Firefox 驱动的 Selenium 实例?

我已经能够通过在我的 obj.put 调用中特别包含 content-type header 来防止这种情况的进一步发生。具体来说,该行现在看起来像:

obj.put(body: open(REMOTE_PATH_TO_IMAGE), acl: 'public-read', content_type: "image/jpeg")

值得注意的是,在将损坏的图像导入到 S3 之后设置内容类型不会de-corrupt图像。所以问题不在于 S3 没有响应图像的有效 headers,而是在导入时发生损坏。当时我有一种强烈的预感,但这让我更清楚地了解了这个问题。