php把網路圖片轉化為base64格式,解決html2canvas圖片跨域問題
一、前言
最近在用html2canvas
做網頁截圖功能。這個開源庫使用很簡單,程式碼也很方便,但難點在於跨域問題。比如說,我的一個頁面中有圖片也有文字,圖片是來自於圖片伺服器的網路圖片。此時我們要生成截圖的話,需要有許可權來操作網路圖片,這就出現了跨域問題。
這篇部落格主要是從php方向把網路圖片轉化為base64格式,從而避免圖片跨域的出現。
二、html2canvas常見的跨域解決方案
1、修改html2canvas.js
的原始碼部分
這部分是網路上一個大佬修改的,大家如果遇到這個問題的話,應該都能搜到那些文章。博主這裡也引用了修改過的原始碼,但是毫無用處。
程式碼分享:
//這部分是修改過的原始碼
連結: https://pan.baidu.com/s/1d9DnX2L3xtgima01Ridi5A 密碼: yhub
2、設定伺服器的header頭
這部分也是要看後端配合不配合的,如果配合的話,直接在被請求伺服器方法的頂部加上:
//表明允許跨域訪問
Access-Control-Allow-Origin:你伺服器的ip地址
博主這裡沒有操作圖片伺服器的許可權,所以就不提了。
3、設定php代理
在html2canvas
開源庫中,給出的有php代理程式碼。實話實說,我是看不懂這個有什麼用。不過還是有人通過這種方式程成功實現跨域了的。
//新加一個proxy屬性,並把你的代理檔案引入進去。如果無效的話,可以通過:你的域名/程式碼檔案路徑,檢視報錯是什麼
html2canvas(dom, {
"logging": true,
"proxy":"{{asset('/html2canvasproxy.php')}}",//跨域支援
canvas:canvas,
background: "#fff",
useCORS: true,
onrendered: function (canvas) {
}
連結: 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