1

截屏一直以来,就是客户端的专利,对于浏览器端可谓无能为力。

不过,自从canvas出来以后,就不一样了。

HTML5中canvas的方法,toDataURL() 可将canvas的内容保存为图片。

简单保存canvas图片的代码如下:

function convertCanvasToImage(canvas) {
    var image = new Image();
    image.src = canvas.toDataURL("image/png");
    return image;
}

对于普通canvas截图没有问题,甚至对于整个DOM树也可以先转换成canvas,然后转换成截图。业界有成熟的类似的类库 html2canvas

问题

工作中,需要对地图截图,遇到不少问题,折腾了很久,在此记录。

原图:

最后的截图代码:

JS Bin on jsbin.com

问题一 跨域

截图失败,浏览器提示:

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

为什么会出现跨域问题呢?仔细一想,地图上有一些图片,存储在地图服务商的服务器,当我们toDataURL的时候取不到图片数据,跨域也就能够想通了。

解决方式,暂时不获取跨域图片,直接try catch掉。暂时能够截图,看到的效果:

问题二 圆角模糊

如上图中,圆形中间多了一个叉,暂时不知道原因,解决方式是在截图前去除圆角。

问题三 图片不显示

其实是问题一留下的问题,截图左下角,有个高德的图片没有显示,问题一解决方式是绕过,但问题还是要解决。

在服务器端,是不存在跨域。所以,问题三的解决方式,我们可以在本地起一个代理服务器,代理通过获取图片,然后设置setHeader('Access-Control-Allow-Headers', '*’); 然后给本地浏览器使用。

代理服务器代码:

JS Bin on jsbin.com

通过服务器跨域,然后允许所有访问图片,就可以跨域了。

问题四 地理名称不显示

通过上图可以看到,地图截图所有的地理位置名称都没有。打开log后可以看到,问题还是出在跨域上。地图所有的地理位置名称也是通过图片实现,图片存在地图服务商的服务器上,通过canvas渲染,和问题三的单纯的图片不太一样。

要解决这个问题,必须地图服务器设置Header为”Access-Control-Allow-Headers: *”。通过公司关系,和高德产品经理、开发联系过,对方回答没办法设置这个,处于安全考虑。于是,这个问题无解。

最后效果:

原创文章,欢迎转载。转载请注明:转载自Fs21 ' s Home,谢谢!
原文链接地址:前端地图截屏方案


瞿宝明
159 声望12 粉丝

滴滴,前端