截屏一直以来,就是客户端的专利,对于浏览器端可谓无能为力。html
不过,自从canvas出来之后,就不同了。前端
HTML5中canvas的方法,toDataURL()
可将canvas的内容保存为图片。canvas
简单保存canvas图片的代码以下:跨域
function convertCanvasToImage(canvas) { var image = new Image(); image.src = canvas.toDataURL("image/png"); return image; }
对于普通canvas截图没有问题,甚至对于整个DOM树也能够先转换成canvas,而后转换成截图。业界有成熟的相似的类库 html2canvas 。浏览器
工做中,须要对地图截图,遇到很多问题,折腾了好久,在此记录。安全
原图:服务器
最后的截图代码:spa
截图失败,浏览器提示:code
`Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.`
为何会出现跨域问题呢?仔细一想,地图上有一些图片,存储在地图服务商的服务器,当咱们toDataURL的时候取不到图片数据,跨域也就可以想通了。
解决方式,暂时不获取跨域图片,直接try catch掉。暂时可以截图,看到的效果:
如上图中,圆形中间多了一个叉,暂时不知道缘由,解决方式是在截图前去除圆角。
实际上是问题一留下的问题,截图左下角,有个高德的图片没有显示,问题一解决方式是绕过,但问题仍是要解决。
在服务器端,是不存在跨域。因此,问题三的解决方式,咱们能够在本地起一个代理服务器,代理经过获取图片,而后设置setHeader('Access-Control-Allow-Headers', '*’);
而后给本地浏览器使用。
代理服务器代码:
经过服务器跨域,而后容许全部访问图片,就能够跨域了。
经过上图能够看到,地图截图全部的地理位置名称都没有。打开log后能够看到,问题仍是出在跨域上。地图全部的地理位置名称也是经过图片实现,图片存在地图服务商的服务器上,经过canvas渲染,和问题三的单纯的图片不太同样。
要解决这个问题,必须地图服务器设置Header为”Access-Control-Allow-Headers: *”。经过公司关系,和高德产品经理、开发联系过,对方回答没办法设置这个,处于安全考虑。因而,这个问题无解。
最后效果:
原创文章,欢迎转载。转载请注明:转载自Fs21 ' s Home,谢谢!
原文连接地址:前端地图截屏方案