在WordPress中用Blob和Ajax实现图片存储与展示的技术问题
基于WordPress的文档照片上传与存储问题
我正在开发一个WordPress网站,功能是让用户拍摄文档照片后上传到服务器存储,供教师等人员审核照片是否合规。我现在是把图片转换成Blob对象,再用Ajax发送到服务器,但作为Web开发新手,我不知道怎么把图片存储到WordPress数据库,也不清楚后续怎么把Blob还原成图片展示。以下是我目前写的代码:
HTML代码
<table> <tr> <td><video autoplay="true" id="video"></video></td> <td><canvas id="canvas"></canvas></td> <td><button id="btn"> Take Picture </button></td> <td><button id="sub"> Einreichen </button></td> </tr> </table>
JavaScript代码(含WordPress钩子)
// 加载jQuery wp_enqueue_script('jquery'); // 定义AJAX地址 function myplugin_ajaxurl() { echo '<script type="text/javascript"> var ajaxurl = "' . admin_url('admin-ajax.php') . '"; </script>'; } add_action('wp_head', 'myplugin_ajaxurl'); // 前端脚本 function add_this_script_footer(){ ?> <script> const video = document.querySelector('#video') const btn = document.querySelector('#btn') const canvas = document.querySelector('#canvas') const submit = document.querySelector('#sub') const photo = document.querySelector('#photo') var capturedBlob; function capturePhoto() { canvas.width = 500; canvas.height = 600; const ctx = canvas.getContext("2d"); ctx.drawImage(video, 0, 0); canvas.toBlob(function(blob) { // 预览图片 const img = document.createElement('img'); img.src = URL.createObjectURL(blob); document.body.appendChild(img); capturedBlob = blob; }, "image/jpeg", 0.75); } if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) { navigator.mediaDevices.getUserMedia({video: true}) .then(stream => { video.srcObject = stream }) .catch(error => { console.log('访问摄像头时出错。') }) } btn.addEventListener('click', capturePhoto); jQuery(document).ready(function($) { $("#sub").click(function() { if (!capturedBlob) { alert('请先拍摄照片!'); return; } const formData = new FormData(); formData.append('action', 'example_ajax_request'); // 给Blob添加文件名,方便后端识别 formData.append('file', capturedBlob, 'document_photo_' + Date.now() + '.jpg'); $.ajax({ url: ajaxurl, type: 'POST', data: formData, processData: false, contentType: false, success:function(data) { const response = JSON.parse(data); if (response.success) { alert('上传成功!图片ID:' + response.attachment_id); } else { alert('上传失败:' + response.error); } }, error: function(errorThrown){ alert('请求出错:' + errorThrown.responseText); } }); }); }); </script> <?php } add_action('wp_footer', 'add_this_script_footer');
原PHP代码
// 处理AJAX请求的PHP function example_ajax_request() { if ( isset($_POST) ) { $file = $_FILES['file']; echo $file; // 这里需要添加文件存储逻辑 // 返回结果给前端 //echo $file; } die(); } add_action( 'wp_ajax_example_ajax_request', 'example_ajax_request' ); add_action( 'wp_ajax_nopriv_example_ajax_request', 'example_ajax_request' );
解决方案
一、修复前端Blob传递问题
原代码存在核心问题:传递Blob时未指定文件名,导致后端无法正确识别为文件。修正后的JS代码做了以下优化:
- 变量名改为
capturedBlob,语义更清晰 - 传递FormData时为Blob指定唯一文件名:
formData.append('file', capturedBlob, 'document_photo_' + Date.now() + '.jpg') - 添加未拍摄照片时的提示逻辑
二、后端将图片存储到WordPress媒体库(推荐方案)
WordPress媒体库自带文件管理、权限控制、缩略图生成等功能,比直接操作数据库更规范。修改PHP处理函数如下:
function example_ajax_request() { // 权限验证:仅允许登录用户上传(可根据需求调整) if (!is_user_logged_in()) { wp_send_json_error('请先登录!'); } // 检查文件上传状态 if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) { wp_send_json_error('文件上传失败,请重试!'); } $file = $_FILES['file']; $upload_dir = wp_upload_dir(); $file_path = $upload_dir['path'] . '/' . basename($file['name']); // 将临时文件移动到WordPress上传目录 if (!move_uploaded_file($file['tmp_name'], $file_path)) { wp_send_json_error('无法保存文件到服务器!'); } // 准备媒体库附件数据 $attachment_data = array( 'guid' => $upload_dir['url'] . '/' . basename($file['name']), 'post_mime_type' => $file['type'], 'post_title' => sanitize_file_name(basename($file['name'])), 'post_content' => '', 'post_status' => 'inherit' ); // 将文件添加到媒体库 $attachment_id = wp_insert_attachment($attachment_data, $file_path); // 生成附件元数据(缩略图、尺寸信息等) require_once(ABSPATH . 'wp-admin/includes/image.php'); $attachment_metadata = wp_generate_attachment_metadata($attachment_id, $file_path); wp_update_attachment_metadata($attachment_id, $attachment_metadata); // 返回成功信息与图片URL wp_send_json_success(array( 'attachment_id' => $attachment_id, 'image_url' => wp_get_attachment_url($attachment_id) )); die(); } add_action( 'wp_ajax_example_ajax_request', 'example_ajax_request' ); add_action( 'wp_ajax_nopriv_example_ajax_request', 'example_ajax_request' );
三、还原并展示图片
存储到媒体库后,有两种常用展示方式:
- 通过附件ID获取URL:使用WordPress内置函数
wp_get_attachment_url($attachment_id)获取图片完整URL,直接在前端用<img src="图片URL">展示。 - 自定义字段存储(不推荐):若需将图片内容存在自定义表,需先把Blob转为Base64字符串存储,展示时用
<img src="data:image/jpeg;base64,Base64字符串">,但这种方式性能远不如媒体库。
四、额外优化建议
- 权限控制:给审核页面添加角色验证,比如仅允许
editor或自定义教师角色访问。 - 合规检查:后端可添加图片尺寸、文件大小校验,甚至结合OCR识别文档内容。
- 错误日志:在PHP中添加错误日志记录,方便排查上传失败问题。
内容的提问来源于stack exchange,提问作者Krupp J
相关产品推荐
相关产品推荐

