全国服务热线:4008-888-888

技术知识

详解canvas.toDataURL()出错的处理计划方案统统在这

出错详细信息内容

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

重要词

  • canvas.toDataURL()
  • crossOrigin
  • Access-Control-Allow-Origin

序言

近期在做1个艺术创意类的照片生成专用工具,大约齐便是根据拼接自定的文本和照片信息内容转化成1张产品照片相近的作用,新项目选用到了fabric.js这个画板库,最终1步在储存照片的情况下报上面的1长串不正确,墙内墙外搜了1遍,得出的处理计划方案都不全面,为防止同学们再度踩坑,因而有了此文

文章正文

大家在convertDOM2Image时,假如DOM运行内存在照片資源,该資源所属的web-server是不适用跨域的,储存照片是不容易取得成功的。

因而在清查难题时,最先要明确

  • web-server是不是容许跨域,大家以nginx为例,response-header内要存在Access-Control-Allow-Orgin:xxxx(能够是*,安全性性规定较为高的能够依据主网站域名自定)
  • 假如是img标识, 是不是加上了crossorigin="anonymous", 假如是Image目标,一样是不是加上了改特性obj.crossOrigin='anonymous'
  • 假如还不好,这里先不把回答放出来,大家先看看栗子

在接下来的栗子中大家会用到将Image变换为canvas目标的方式

function convertImageToCanvas(image) {
// 建立canvas DOM元素,并设定其宽高和照片1样 
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
// 大家在具体的开发设计中,必须将抓换后的base64照片编号传送到后台管理照片服务器,由server立即储存或转化成1张照片;
// 因此会用到 toDataURL
console.log(canvas.toDataURL('image/jpeg'))
return canvas;
}

栗子1

当地未设定跨域容许选项crossorigin=anonymous,web-server未设定跨域容许选项

<div id="d1">
<img style="width: 300px;height: 240px;" src="http://jb51.net/images/cover_thumbnail_3rd.jpg" alt="">
<p>当地未设定跨域容许选项crossorigin=anonymous,web-server未设定跨域容许选项</p>
</div>
<button onclick="setCanvas('d1')">canvas储存</button>
function setCanvas(DOMID) {
let img = document.getElementById(DOMID).querySelector('img')
document.body.appendChild(convertImageToCanvas(img))
}

很明显,出错

栗子2

当地标识内设定跨域容许选项, web-server未设定跨域容许选项

这次连照片都出不来,立即出错

这个好了解,访问器同宗对策限定嘛

Access to image at 'xxxx' (redirected from 'xxxx') from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

栗子3

当地未设定跨域容许选项crossorigin=anonymous, web-server设定跨域容许选项

出错,妥妥的。

栗子4

当地标识内设定跨域容许选项crossorigin=anonymous, web-server设定跨域容许选项

<div id="d4">
<img style="width: 300px;height: 240px;" src="https://img.alicdn.com/tfs/TB1_uT8a5ERMeJjSspiXXbZLFXa⑴43⑸9.png" alt="" crossorigin="anonymous">
<p>当地设定跨域容许选项`crossorigin=anonymous`,`web-server`设定跨域容许选项</p>
</div>
<button onclick="setCanvas('d4')">canvas储存</button>

竟然能够了,可是~假如在编码内设定跨域呢?

栗子5

function setCanvas(DOMID) {
let img = document.getElementById(DOMID).querySelector('img')

img.crossOrigin= 'anonymous'

document.body.appendChild(convertImageToCanvas(img))
}

出错

我看官方文本文档的意思是务必同歩设定crossOrigin=anonymous,该照片凭据才会被信赖

This means that CORS is enabled and credentials are sent if the image is fetched from the same origin from which the document was loaded.

不然缓存文件的图象数据信息依然会被画布视作有污染的跨源內容.

如何办?再次取1遍照片呗,加个任意数,照片還是那个照片,但是加了个马甲,访问器就不了解了

栗子6

function setCanvas(DOMID) {
let img = document.getElementById(DOMID).querySelector('img')

img.src =img.src+'?v='+Math.random()
img.crossOrigin= 'anonymous'

img.onload=()=>{
document.body.appendChild(convertImageToCanvas(img))
}
}

binggo, 完善处理

因此大家在开发设计全过程中,新建照片,拆换照片,复原照片等作用编码内,最好是每次都加个任意数,以确保源全是全新的,不走缓存文件

多说1点吧,有关fabric.js的有关跨域配备见正下方

let _fabricConfig = {
// ....
crossOrigin:'anonymous'
};
/* fabric目标 */
let _fabricObj = new fabric.Canvas(id, _fabricConfig);


// 新建照片目标时
let imgInstance = new fabric.Image.fromURL(url + '?v='+ Math.random(), img => {}, {crossOrigin: 'anonymous'})

// 动态性升级照片时
let currentActive = _fabricInstance.getActiveObj();
currentActive.setSrc(randomURL, img =>{}, {crossOrigin: 'anonymous'})

github:http://github.com/phillyx

到此这篇有关详解canvas.toDataURL()出错的处理计划方案统统在这了的文章内容就详细介绍到这了,更多有关canvas.toDataURL()出错內容请检索脚本制作之家之前的文章内容或再次访问下面的有关文章内容,期待大伙儿之后多多适用脚本制作之家!



在线客服

关闭

客户服务热线
4008-888-888


点击这里给我发消息 在线客服

点击这里给我发消息 在线客服