You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas.toDataURL转PHP base64解码乱码,如何适配WP文件上传逻辑?

问题:Canvas生成的Base64图片字符串转存适配原有PHP上传逻辑失败

问题背景

我尝试把Canvas通过canvas.toDataURL('image/png')生成的Base64图片字符串,用AJAX发送到PHP后解码保存到文件夹。生成的字符串格式如下:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXYAAAF1CAYAAAD8ysHLAAAgAElEQVR4XuydCbiOVff/lw...

字符串长度约43000字符,按网上方案解码后得到“乱码”内容,没法适配之前正常运行的文件上传逻辑。


当前代码

AJAX请求代码

form_data = new FormData();
form_data.append('file', newImage);
form_data.append('action', 'file_upload');
form_data.append('security', blog.security);

// 发送AJAX请求
$.ajax({
    url: blog.ajaxurl,
    type: 'POST',
    contentType: false,
    processData: false,
    data: form_data, ...

PHP解码代码

$img64String = $_POST['file'];
$img64String = str_replace('data:image/png;base64,', '', $img64String);
$img64String = str_replace(' ', '+', $img64String);
$fileData = base64_decode($img64String);

解码后内容示例(所谓“乱码”)

FileData: �PNG IHDRvu���� IDATx^�    ��U���eʔ!    !
%��Pр$C*�FC��FD��&�(RRƷdJ�䯼Pʔyʐ�����?�s�9g�������ֺ.W�s�}��| 
��߽�����8�?&fF�#�@��5si�#�dka�����f�i�? 
���d�1'ݔ'�#�k���Ʉ]7��V&�...

原有正常运行的PHP上传逻辑

$file_type = $_FILES['file']['type'];
$file_name = $_FILES['file']['name'];
$file_temp_name = $_FILES['file']['tmp_name'];

$allowed_file_types = array('image/png', 'image/jpeg', 'image/jpg');
if (in_array($file_type, $allowed_file_types)) {
    $upload = wp_upload_bits($file_name, null, file_get_contents($file_temp_name));
    $status = "ok";
}

问题分析与解决方案

  1. “乱码”是正常现象:你看到的乱码是PNG图片的二进制原始内容,说明Base64解码已经成功了,不是解码失败。
  2. 适配原有逻辑的核心问题:原有代码依赖$_FILES数组,但你现在是通过$_POST传递Base64字符串,不需要硬套$_FILES的逻辑,直接把解码后的二进制数据传给wp_upload_bits即可。

修正后的PHP代码

// 获取前端传来的Base64字符串
$img64String = $_POST['file'];

// 剥离Base64前缀(兼容png/jpg/jpeg)
$img64String = preg_replace('/^data:image\/(png|jpeg|jpg);base64,/', '', $img64String);
// 替换空格为+(处理URL编码可能导致的字符转换)
$img64String = str_replace(' ', '+', $img64String);
// 解码得到图片二进制数据
$fileData = base64_decode($img64String);

// 提取图片类型并生成文件名
preg_match('/^data:image\/(png|jpeg|jpg);base64,/', $_POST['file'], $matches);
$file_type = 'image/' . $matches[1];
$file_ext = $matches[1];
$file_name = 'canvas_upload_' . time() . '.' . $file_ext; // 用时间戳避免文件名重复

// 复用原有验证逻辑
$allowed_file_types = array('image/png', 'image/jpeg', 'image/jpg');
if (in_array($file_type, $allowed_file_types) && $fileData !== false) {
    // 直接传递二进制数据给wp_upload_bits,不需要临时文件
    $upload = wp_upload_bits($file_name, null, $fileData);
    $status = "ok";
} else {
    $status = "error";
}

关键优化说明

  • 动态提取图片类型,避免硬编码,适配多种图片格式;
  • 增加$fileData !== false判断,过滤Base64解码失败的无效数据;
  • 用时间戳生成文件名,避免重复覆盖问题。

内容的提问来源于stack exchange,提问作者eligolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:55:34