首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 接收 HTML5 Canvas 圖像並保存到服務器完整實現

     編輯:PHP 綜合知識

從電子簽名到圖片上傳:Canvas 數據服務端保存全流程解析

HTML5 Canvas 賦予瀏覽器原生繪圖能力,但如何將用戶在畫布上的創作(如電子簽名、繪圖編輯)持久化到服務器?本文通過實際項目場景,詳細講解 Canvas 圖像數據的前端獲取、Base64 編碼傳輸、PHP 端解碼存儲全鏈路實現。

業務場景回顧

早期項目需求:專家評審系統要求專家在平板上手寫簽名。當時採用 Flash/ActiveX 方案極其繁瑣。如今 Canvas + Base64 + PHP 方案幾十行代碼即可搞定。

核心技術鏈路

Canvas繪圖 → toDataURL()獲取Base64 → AJAX POST傳輸 → PHP base64_decode → 文件存儲

前端關鍵代碼

<canvas id="signaturePad" width="400" height="200"></canvas>
<button onclick="saveSignature()">保存簽名</button>

<script>
function saveSignature() {
    const canvas = document.getElementById('signaturePad');
    // 獲取 Base64 Data URL (格式: data:image/png;base64,xxxx)
    const dataURL = canvas.toDataURL('image/png');
    
    // 發送到後端
    fetch('save_canvas.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        body: 'img=' + encodeURIComponent(dataURL)
    }).then(res => res.text()).then(console.log);
}
</script>

PHP 服務端完整實現

<?php
// save_canvas.php
// 需 PHP 5.4+

// 1. 配置上傳目錄
define('UPLOAD_DIR', __DIR__ . '/uploads/signatures/');
if (!is_dir(UPLOAD_DIR)) {
    mkdir(UPLOAD_DIR, 0755, true);
}

// 2. 接收並清洗 Base64 數據
$img = $_POST['img'] ?? '';
if (empty($img)) {
    die('無圖像數據');
}

// 移除 Data URL 頭部信息
$img = str_replace('data:image/png;base64,', '', $img);
// 修正空格轉義問題(+ 被編碼為空格)
$img = str_replace(' ', '+', $img);

// 3. Base64 解碼
$data = base64_decode($img);
if ($data === false) {
    die('Base64 解碼失敗');
}

// 4. 生成唯一文件名並存儲
$filename = uniqid('sign_', true) . '.png';
$filepath = UPLOAD_DIR . $filename;

$success = file_put_contents($filepath, $data);
if ($success === false) {
    die('文件寫入失敗');
}

// 5. 返回結果
echo json_encode([
    'success' => true,
    'filename' => $filename,
    'url' => '/uploads/signatures/' . $filename
]);
?>

關鍵技術點深度解析

Data URL 格式標準

data:[][;base64],
// 實例:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
  • mediatype:MIME 類型,Canvas 常用 image/png、image/jpeg
  • ;base64:標證數據經 Base64 編碼
  • 逗號後為實際編碼數據

Base64 解碼陷阱與對策

問題原因解決方案
解碼後圖片損壞空格被編碼為 + 號str_replace(' ', '+', $data)
文件體積為 0未移除 Data URL 前綴str_replace('data:image/png;base64,', '', $data)
大文件內存溢出Base64 體積約為原文 4/3分塊上傳 / 調大 memory_limit / 使用流式處理

安全性加固建議

  1. 文件類型驗證:解碼後用 getimagesize() 或 finfo_file() 驗證真實 MIME
  2. 文件大小限制:設置 post_max_size、upload_max_filesize 並校驗 strlen($data)
  3. 存儲路徑隔離:上傳目錄禁止腳本執行權限,Nginx 配置 location ~* \.php$ { deny all; }
  4. 文件名隨機化:使用 uniqid() 或 bin2hex(random_bytes(16)) 防止覆蓋與遍歷

擴展應用場景

  • 圖片編輯器保存:Cropper.js、Fabric.js 編輯後導出
  • 電子合同簽署:多頁 PDF 每頁渲染到 Canvas 再合成
  • 數據可視化導出:ECharts/Highcharts 圖表導出為圖片報表
  • 遊戲截圖分享:Canvas 遊戲關卡成果生成分享圖

這套方案純前後端分離、無第三方依賴、兼容性極佳(IE9+),是 Canvas 數據服務端落地的標準範式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved