
本文详解 Summernote v0.8.18 中通过 onMediaDelete 回调安全删除编辑器内图片的完整流程,涵盖前端事件绑定、路径正确传递、AJAX 请求构造及后端 PHP 文件清理逻辑,避免常见 undefined src 错误。
本文详解 summernote v0.8.18 中通过 `onmediadelete` 回调安全删除编辑器内图片的完整流程,涵盖前端事件绑定、路径正确传递、ajax 请求构造及后端 php 文件清理逻辑,避免常见 `undefined src` 错误。
Summernote 默认不提供服务端文件删除能力,需开发者手动监听 onMediaDelete 事件并触发 AJAX 请求完成清理。关键在于:$target[0].src 是原生 DOM 元素的 src 属性值(即完整 URL 字符串),不应再用 jQuery 的 .attr("src") 二次读取,否则因 this 指向错误导致 undefined。
✅ 正确的前端实现
$('#summernote').summernote({
height: 400,
callbacks: {
onImageUpload: function(files, editor, welEditable) {
sendFile(files[0], editor, welEditable); // 上传逻辑(略)
},
onMediaDelete: function($target) {
// $target 是 jQuery 对象,$target[0] 是原生 img 元素
const imageUrl = $target[0].src; // ✅ 直接获取 src 字符串,如 "http://localhost/news/uploads/large/6dBUlfZZBW.webp"
deleteFile(imageUrl);
$target.remove(); // 从 DOM 移除元素
}
}
});
function deleteFile(path) {
$.ajax({
url: 'delete_summernote.php',
type: 'POST',
data: { path: path }, // ✅ 以键值对形式传参,非直接传字符串
dataType: 'json',
success: function(resp) {
console.log('删除成功:', resp.message);
},
error: function(xhr) {
console.error('删除失败:', xhr.responseText);
}
});
}
⚠️ 注意事项:
- 不要写 var src = $(this).attr("src") —— 此处 this 指向 window,非目标元素;
- data: src 是错误用法(将整个 URL 字符串当作请求体),应使用 data: { path: src };
- 前端 URL 路径需与后端可访问的物理路径对应(见下文转换逻辑)。
✅ 安全的后端处理(PHP)
由于前端传入的是 Web 可访问 URL(如 http://localhost/news/uploads/large/xxx.webp),而 unlink() 需要 服务器绝对路径,必须做安全转换:
<?php // delete_summernote.php
header('Content-Type: application/json; charset=utf-8');
if (!isset($_POST['path']) || empty($_POST['path'])) {
echo json_encode(['success' => false, 'message' => '缺少 path 参数']);
exit;
}
$webUrl = filter_var($_POST['path'], FILTER_SANITIZE_URL);
$baseDir = __DIR__; // 当前 PHP 文件所在目录,例如 C:\wamp64\www\
// 安全地将 URL 转为绝对路径(仅允许子目录)
$relativePath = parse_url($webUrl, PHP_URL_PATH); // 获取 /news/uploads/large/xxx.webp
if (!$relativePath) {
echo json_encode(['success' => false, 'message' => 'URL 格式无效']);
exit;
}
// 去除开头斜杠,并拼接为真实路径
$filePath = realpath($baseDir . $relativePath);
// 关键校验:确保路径落在项目目录内,防止路径遍历攻击
if ($filePath === false || strpos($filePath, $baseDir) !== 0) {
http_response_code(403);
echo json_encode(['success' => false, 'message' => '非法路径访问']);
exit;
}
if (file_exists($filePath) && is_file($filePath)) {
if (unlink($filePath)) {
echo json_encode(['success' => true, 'message' => '文件已删除']);
} else {
echo json_encode(['success' => false, 'message' => '文件删除失败(权限不足)']);
}
} else {
echo json_encode(['success' => false, 'message' => '文件不存在']);
}
? 常见错误排查
| 现象 | 原因 | 解决方案 |
|---|---|---|
| Warning: Undefined array key "src" | PHP 中误用 $_FILES['src'](src 是 POST 数据,非上传文件) | 改用 $_POST['path'] |
| 403 Forbidden 或删除无反应 | 后端未做路径合法性校验,或 unlink() 权限不足 | 添加 realpath() + strpos() 校验,检查 Web 服务器用户对文件的写权限 |
| 控制台报 Cannot read property 'src' of undefined | $target[0] 为空(如删除非 |
增加类型判断:if ($target[0].tagName === 'IMG') |
✅ 总结
实现 Summernote 图片服务端删除的核心是:
① 前端精准提取 img.src 字符串并以结构化方式({path: xxx})提交;
② 后端严格校验 URL 转换后的物理路径,杜绝路径穿越风险;
③ 统一返回 JSON 响应便于前端调试。
此方案兼容 WAMP/XAMPP/LNMP 环境,兼顾安全性与可维护性。










