javascript - 如何使用 html2Canvas 和 AWS S3 图像处理 CORS?

标签 javascript canvas amazon-s3

我知道以前有人问过类似的问题,但我仍然无法解决。我有一个 div,其中包含从 AWS s3 中的存储桶加载的图像,它们完全加载没有问题。

现在我希望能够将特定 div 中的任何内容保存为 jpeg(例如截屏),插件 html2canvas 可以帮助实现这一点。问题是,当我尝试实际保存它(或只是立即显示此类屏幕截图的结果)时,我遇到了这些问题:

  • Canvas is tainted => 我在插件中设置了 allowTaint: true 但它会抛出这个错误,所以我禁用它并且错误消失了。我将 useCORS 设置为 true 以允许来自其他来源的图像。

  • 对图像的访问已被 CORS 策略阻止

为了解决这个问题,我在我的 AWS S3 存储桶上设置了 CORS,但这似乎不起作用(或部分起作用)。我注意到当插件使用它们生成 jpeg 时,这些图像的响应 header 没有 CORS 元数据。然后我尝试在 div 内的那些图像中设置 crossOrigin="anonymous" 但它会立即引发 CORS 错误,这不应该发生,因为 AWS 存储桶有为此设置如下:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

关于如何完成这项工作,我的选择已经用完了。任何关于如何从这里开始的想法将不胜感激。

编辑:更多细节,我正在使用 React 并且图像 url 是从服务器检索的。这意味着一旦我得到这个 url 数组,我就会生成:

<div>
  { urls.map(url => <img src={url} alt="some alt" />) }
</div>

如果我添加 crossOrigin="anonymous" 我会收到 CORS 错误。如果我忽略它,图像会显示,但 html2canvas 插件在尝试生成“屏幕截图”时也会抛出 CORS 错误。

有关 HTTP 请求的更多详细信息。所以我第一次在 div 中加载图像时,这是响应 header :

Accept-Ranges:bytes
Access-Control-Allow-Methods:GET
Access-Control-Allow-Origin:*
Cache-Control:max-age=2592000
Content-Length:508208
Content-Type:image/png
Date:Thu, 16 Feb 2017 18:25:05 GMT
Last-Modified:Wed, 15 Feb 2017 19:09:44 GMT
Server:AmazonS3
Vary:Origin, Access-Control-Request-Headers, Access-Control-Request-Method 

现在,如果 crossOrigin='anonymous' 并且图片不是来自缓存,这将起作用。如果未设置 crossOrigin 属性,我会得到:

Accept-Ranges:bytes
Cache-Control:max-age=2592000
Content-Length:508208
Content-Type:image/png
Date:Thu, 16 Feb 2017 19:03:53 GMT
Last-Modified:Wed, 15 Feb 2017 19:09:44 GMT
Server:AmazonS3

或者它会在控制台上抛出 CORS 错误,而不会在响应 header 上显示任何元数据。我尝试在 url 的末尾添加一个随机字符串 (?somethingsomething),这样它们就永远不会从缓存中被抓取,这完全解决了这个问题。但这只是一个 hack,它现在可以工作,但它绝对不是我正在寻找的解决方案。我认为 Chrome 正在对缓存做一些事情,我很难跟踪问题的根源,除了很难在我的机器上重现这个问题,因为它总是从缓存中检索屏幕截图,即使我完全使用新图像和禁用/清除缓存。这非常令人困惑。

最佳答案

See the edit, I did try setting the crossOrigin attribute with no luck, and I use useCORS set to true (forgot to mention that sorry). Still no luck.

我修复了结合使用 Google Chrome、AWS S3 和多个来源时遇到的一些 cors 问题。

我发现了这个 stackoverflow 线程: Chrome + CORS + cache - requesting same file from two different origins

此错误报告的链接: https://bugs.chromium.org/p/chromium/issues/detail?id=260239

无论如何,作为变通解决方案,您可以尝试这个修改后的 html2canvas 版本: https://gist.github.com/CrandellWS/6bc2078aced496004d7a045e6360f19b

使用选项:

allowTaint : false,
useCORS: true

希望对您有所帮助。

仅供引用,这会将当前时间戳添加到 cors 图像 url 以回避我在 Chrome 上遇到的缓存问题... https://gist.github.com/CrandellWS/6bc2078aced496004d7a045e6360f19b#file-html2canvas-js-L6838

这意味着它将通过重新下载这些图像来影响性能...

原帖: https://github.com/niklasvh/html2canvas/issues/1544#issuecomment-435640901

关于javascript - 如何使用 html2Canvas 和 AWS S3 图像处理 CORS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42263223/

相关文章:

javascript - 为什么我似乎无法正确实现此功能?

javascript - 通过每个循环创建具有多个属性的对象

c# - 如何将整个可滚动 Canvas 另存为 Png

javascript - 无法执行 'getImageData' - Canvas 已被跨源数据污染

django 无法在 heroku 上提供 gzip

amazon-web-services - 如何将运动视频流存储到 S3 存储桶中?

windows - aws s3 命​​令在 Windows 任务计划程序触发的批处理文件中不起作用

<a> 的 javascript:void(0) 或 onclick ="return false"- 哪个更好?

javascript - 从(Ajax 输出)传递返回的数组以在任何地方用作全局变量

javascript - 从点的视线