我知道之前已经提出了类似的问题,但我仍然无法使其发挥作用。我有一个div
,其中包含从AWS s3中的存储桶加载的图像,它们完全没有问题。
现在我希望能够将jpeg保存为特定div
中的任何内容(如截取屏幕截图),插件html2canvas
有助于此。问题是,当我尝试实际保存它(或者只是立即显示这种屏幕截图的结果)时,我遇到了这些问题:
画布受污染=>我在插件中设置allowTaint: true
但它会抛出此错误,因此我禁用了它并且错误消失了。我将useCORS
设置为true
,但允许来自其他来源的图片。
CORS政策阻止了对图片的访问
为了解决这个问题,我在我的AWS S3存储桶上设置了CORS,但这似乎不起作用(或者它部分工作)。我注意到,当插件使用它们生成jpeg时,这些图像的响应头没有CORS元数据。然后我尝试在crossOrigin="anonymous"
内的那些图像中设置div
,但它会立即抛出一个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并从服务器检索图像网址。这意味着,一旦我得到这个网址数组,我就会生成:
<div>
{ urls.map(url => <img src={url} alt="some alt" />) }
</div>
如果我添加crossOrigin="anonymous"
,我会收到CORS错误。如果我将其删除,则显示图像,但是当试图生成“屏幕截图”时,html2canvas
插件也会引发CORS错误。
有关HTTP请求的更多详细信息。所以我第一次在div
内加载图像时,这就是响应标题:
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错误而没有在响应头上显示任何元数据。我尝试在url(?somethingsomething
)的末尾添加一个随机字符串,以便永远不会从缓存中抓取它们,这完全解决了问题。但这只是一个黑客,它现在可以工作,但它绝对不是我想要的解决方案。我认为Chrome正在对缓存做一些事情,我很难跟踪问题的根源,除了在我的机器上很难重现这个问题的事实,因为它总是从缓存中检索截图,即使我完全使用新图像和禁用/清除缓存。这很令人困惑。
答案 0 :(得分:3)
查看编辑,我确实尝试将crossOrigin属性设置为no 运气好,我将useCORS设置为true(忘了对不起)。 还是没有运气。
我修复了谷歌浏览器,AWS S3和多个来源的结合所带来的一些问题。
我发现了这个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图片网址,从而避免了我在Chrome上遇到的缓存问题... https://gist.github.com/CrandellWS/6bc2078aced496004d7a045e6360f19b#file-html2canvas-js-L6838
这意味着它将通过重新下载这些图像来影响性能...
原始帖子: https://github.com/niklasvh/html2canvas/issues/1544#issuecomment-435640901
答案 1 :(得分:1)
我通过在IMG标签上添加crossOrigin属性解决了该错误。因此,您的代码将如下所示(在React js处标记):
<Image crossOrigin="true" />
我在带有CORS的S3存储桶中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://localhost:8000</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>https://testing.d1wr8lk28mi6l0.amplifyapp.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
HTML2CANVAS:
html2canvas(getWrapper, { allowTaint: true, useCORS: true, logging: true })
.then((canvas) => {
const imgData = canvas.toDataURL('image/png');
console.log(imgData);
});
答案 2 :(得分:0)
我通过在 html2canvas 中添加 proxy:( image src )
选项解决了这个问题。现在您的图片也包含在 pdf 中
打字稿代码:
download() {
var data = document.getElementById('view-eob');
html2canvas(data, { proxy: this.eobDetail.member.parentCompany.logo })
.then(canvas => {
var imgWidth = 208;
var imgHeight = canvas.height * imgWidth / canvas.width;
const contentDataURL = canvas.toDataURL('image/png')
let pdf = new jsPDF('p', 'mm', 'a4');
var position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)
pdf.save(`${this.eobDetail.episode.name}-EOB.pdf`);
});
}
HTML 代码:
<div>
<img [src]="this.eobDetail.member.parentCompany.logo"/>
</div>
<button type="button" (click)="download()"> Download</button>