如何使用PHP+AJAX实现已上传文件在提交或页面重载时删除
实现方案
整体思路是前端记录已上传的临时文件名,在指定两个触发场景调用后端删除接口,后端完成临时文件清理,具体实现步骤如下:
1. 调整前端JS逻辑(drag_drop.js)
首先新增变量存储已上传的临时文件名,新增删除请求函数,绑定两个触发事件:
var fileobj; // 新增:存储已上传的临时文件名 var uploadedTempFile = ''; function upload_file(e) { e.preventDefault(); fileobj = e.dataTransfer.files[0]; ajax_file_upload(fileobj); } function file_explorer() { document.getElementById('selectfile').click(); document.getElementById('selectfile').onchange = function () { fileobj = document.getElementById('selectfile').files[0]; ajax_file_upload(fileobj); }; } function ajax_file_upload(file_obj) { if (file_obj != undefined) { var form_data = new FormData(); form_data.append('file', file_obj); var xhttp = new XMLHttpRequest(); xhttp.open("POST", "/app/helpers/upload_file.php", true); xhttp.onload = function (event) { oOutput = document.querySelector('.img-content'); if (xhttp.status == 200) { if(this.responseText == 'false'){ console.log('no type'); } else { oOutput.innerHTML = "<img src='/app/assets/img/pdf.png' alt='The Image' width='32' height='32'/>\<p>" + this.responseText + "</p>"; // 新增:上传成功后存储临时文件名 uploadedTempFile = this.responseText; } } else { oOutput.innerHTML = "Error " + xhttp.status + " occurred when trying to upload your file."; } } xhttp.send(form_data); } } // 新增:删除临时文件函数 function deleteTempFile() { if (!uploadedTempFile) return; // 页面卸载时用sendBeacon保证请求能发出,避免普通XHR被浏览器中断 if (typeof navigator.sendBeacon !== 'undefined') { const formData = new FormData(); formData.append('filename', uploadedTempFile); navigator.sendBeacon('/app/helpers/delete_temp_file.php', formData); } else { // 兼容低版本浏览器 const xhttp = new XMLHttpRequest(); xhttp.open("POST", "/app/helpers/delete_temp_file.php", false); // 同步请求保证执行完成 const formData = new FormData(); formData.append('filename', uploadedTempFile); xhttp.send(formData); } // 清空已存储的文件名 uploadedTempFile = ''; } // 新增1:绑定页面重载/关闭事件,触发删除 window.addEventListener('beforeunload', function(e) { deleteTempFile(); }); // 新增2:绑定提交按钮点击事件,触发删除(把下面的submit_btn_id改成你实际提交按钮的ID) document.getElementById('submit_btn_id').addEventListener('click', function() { // 如果你提交时需要先把临时文件移动到正式目录、或者读取内容入库,先执行对应逻辑,再调用删除 // ... 你的提交入库逻辑 ... deleteTempFile(); });
2. 新增后端删除接口(/app/helpers/delete_temp_file.php)
注意做路径安全校验,避免恶意用户遍历删除服务器文件:
<?php // 允许删除的后缀,和上传允许的类型对应 $allowedExt = ['pdf', 'doc', 'docx']; $uploadDir = 'uploads/'; if (!isset($_POST['filename'])) { echo 'invalid request'; die; } $filename = $_POST['filename']; // 安全校验1:禁止路径穿越,去掉所有../相对路径 $filename = basename($filename); // 安全校验2:校验文件后缀合法 $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); if (!in_array($ext, $allowedExt)) { echo 'invalid file type'; die; } $filePath = $uploadDir . $filename; // 校验文件存在且在指定临时目录下 if (file_exists($filePath) && dirname(realpath($filePath)) == realpath($uploadDir)) { unlink($filePath); echo 'deleted'; } else { echo 'file not exist'; } die;
3. 可选优化:定时清理临时目录
为了避免用户直接关闭浏览器进程、或者JS执行失败导致的临时文件残留,建议加个定时任务(Linux下用crontab),定期删除uploads目录下超过24小时的文件:
# 每天凌晨2点删除uploads目录下超过1天的文件,把/path/to/your/uploads改成实际目录路径 0 2 * * * find /path/to/your/uploads -type f -mtime +1 -delete
内容的提问来源于stack exchange,提问作者santiago morales
相关产品推荐
相关产品推荐

