php把网络图片转化为base64格式,解决html2canvas图片跨域问题

吕昀
2023-12-01

一、前言

      最近在用html2canvas做网页截图功能。这个开源库使用很简单,代码也很方便,但难点在于跨域问题。比如说,我的一个页面中有图片也有文字,图片是来自于图片服务器的网络图片。此时我们要生成截图的话,需要有权限来操作网络图片,这就出现了跨域问题。

      这篇博客主要是从php方向把网络图片转化为base64格式,从而避免图片跨域的出现。

二、html2canvas常见的跨域解决方案

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

三、最后选择的跨域方案:转换图片为base64

      以上提出的方案都是网友们使用的方案,我这边一个个的试了下,没有一个成功或者符合我的实际需求的。最后没办法了,博主想到用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编码。然后我们就可以用这个编码避免图片跨域问题了,哈哈。

四、html2canvas使用的详细代码

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

 类似资料: