最近在用html2canvas
做网页截图功能。这个开源库使用很简单,代码也很方便,但难点在于跨域问题。比如说,我的一个页面中有图片也有文字,图片是来自于图片服务器的网络图片。此时我们要生成截图的话,需要有权限来操作网络图片,这就出现了跨域问题。
这篇博客主要是从php方向把网络图片转化为base64格式,从而避免图片跨域的出现。
1、修改html2canvas.js
的源码部分
这部分是网络上一个大佬修改的,大家如果遇到这个问题的话,应该都能搜到那些文章。博主这里也引用了修改过的源码,但是毫无用处。
大致链接:
html2canvas截图如何解决跨域的问题?
代码分享:
//这部分是修改过的源码
链接: https://pan.baidu.com/s/1d9DnX2L3xtgima01Ridi5A 密码: yhub
2、设置服务器的header头
这部分也是要看后端配合不配合的,如果配合的话,直接在被请求服务器方法的顶部加上:
//表明允许跨域访问
Access-Control-Allow-Origin:你服务器的ip地址
参考链接:https://blog.csdn.net/c5113620/article/details/79132047
博主这里没有操作图片服务器的权限,所以就不提了。
3、设置php代理
在html2canvas
开源库中,给出的有php代理代码。实话实说,我是看不懂这个有什么用。不过还是有人通过这种方式程成功实现跨域了的。
//新加一个proxy属性,并把你的代理文件引入进去。如果无效的话,可以通过:你的域名/代码文件路径,查看报错是什么
html2canvas(dom, {
"logging": true,
"proxy":"{{asset('/html2canvasproxy.php')}}",//跨域支持
canvas:canvas,
background: "#fff",
useCORS: true,
onrendered: function (canvas) {
}
github相关地址:https://github.com/niklasvh/html2canvas-proxy/issues/2#
分享php代理文件:
链接: https://pan.baidu.com/s/1ytjrCBqQtdYDsUBmh6M_AA 密码: 5724
以上提出的方案都是网友们使用的方案,我这边一个个的试了下,没有一个成功或者符合我的实际需求的。最后没办法了,博主想到用php把网络图片转换为base64编码的,这样就不存在跨域问题了。但是php没有直接转化的方法,毕竟网络图片不同于本地图片。
这篇文章介绍了为什么使用base64位的图片会不存在跨域问题:关于图片的Base64编码,你了解吗?
1、使用curl降网络图片转换为二进制图片流,并先保存在本地
//这里的path是我再本地项目中的临时存储路径:'upload/pictrue/xxx.png'
//这个路径是要提前创建的,类似于一个空的模板,然后通过curl把二进制的图片流写进去
//$url是网络图片的地址
public function curl_file_get_contents($url,$path)
{
$hander = curl_init();
$fp = fopen($path,'wb');
curl_setopt($hander,CURLOPT_URL,$url);
curl_setopt($hander,CURLOPT_FILE,$fp);
curl_setopt($hander,CURLOPT_HEADER,0);
curl_setopt($hander,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($hander,CURLOPT_TIMEOUT,60);
curl_exec($hander);
curl_close($hander);
fclose($fp);
Return $path;
}
这部分看我写的注释,这样就把网络图片转换为了本地图片。返回的是图片的路径
2、把本地图片转换为base64格式的
public function base64EncodeImage ($image_file) {
$base64_image = '';
$image_info = getimagesize($image_file);
$image_data = fread(fopen($image_file, 'r'), filesize($image_file));
$base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));
return $base64_image;
}
这部分是把本地图片的路径当做参数,返回的是图片的base64编码。然后我们就可以用这个编码避免图片跨域问题了,哈哈。
talk is simple,show me the code
var dom=$("#allContent"); //你要转变的dom
var width = dom.width();
var height = width*1.69;
var type = "png";
var scaleBy = 3; //缩放比例
var canvas = document.createElement('canvas');
canvas.width = width * scaleBy; //canvas的宽高都方法3倍
canvas.height = height * scaleBy;
canvas.style.width = width + 'px'; //生成图片时候再缩小回来,这样图片会清晰一些
canvas.style.height = height + 'px';
var context = canvas.getContext('2d');
context.scale(scaleBy, scaleBy);
html2canvas(dom, {
"logging": true,
"proxy":"{{asset('/html2canvasproxy.php')}}",//跨域支持
canvas:canvas,
background: "#fff",
useCORS: true,
onrendered: function (canvas) {
var data = canvas.toDataURL("image/png");//生成的base64格式
//data就是生成的base64码
var id = document.getElementById("id").value;
//下面就是存储生成的截图部分了,是自己的逻辑部分
$.ajax({
url: "你的业务逻辑路径",
type: "post",
dataType: "json",
data: {id:id, data: data},
success: function(r) {
}
});
}
});
以上就是使用html2canvas.js
生成画布的过程。主要就是解决跨域的问题,其他的还好。curl这个工具真的很强大,本来php是没有解析网络图片能力的,通过curl,我们就可以折中实现我们的需求。
end