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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:27:03