首页
学习
活动
专区
圈层
工具
发布

使用纯PHP/AJAX上传进度?

PHP/AJAX 文件上传进度实现指南

基础概念

文件上传进度监控是指在文件上传过程中实时获取上传进度的功能,这对于大文件上传尤其重要,可以改善用户体验。

实现方法

1. 使用 PHP 的 Session Upload Progress

PHP 5.4+ 内置了上传进度跟踪功能,通过 session.upload_progress 配置实现。

配置 php.ini:

代码语言:txt
复制
session.upload_progress.enabled = On
session.upload_progress.cleanup = On
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
session.upload_progress.freq = "1%"

前端实现 (HTML + AJAX):

代码语言:txt
复制
<form id="uploadForm" enctype="multipart/form-data">
    <input type="hidden" name="<?php echo ini_get('session.upload_progress.name'); ?>" value="test" />
    <input type="file" name="file1" />
    <input type="submit" value="Upload" />
</form>

<div id="progress"></div>

<script>
document.getElementById('uploadForm').addEventListener('submit', function(e) {
    e.preventDefault();
    
    var formData = new FormData(this);
    var xhr = new XMLHttpRequest();
    
    // 上传进度事件
    xhr.upload.addEventListener('progress', function(e) {
        if (e.lengthComputable) {
            var percent = Math.round((e.loaded / e.total) * 100);
            document.getElementById('progress').innerHTML = percent + '%';
        }
    }, false);
    
    // 上传完成事件
    xhr.addEventListener('load', function() {
        document.getElementById('progress').innerHTML = 'Upload complete!';
    }, false);
    
    xhr.open('POST', 'upload.php', true);
    xhr.send(formData);
});
</script>

后端处理 (upload.php):

代码语言:txt
复制
<?php
session_start();

// 处理文件上传
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_FILES['file1'])) {
        $uploadDir = 'uploads/';
        $uploadFile = $uploadDir . basename($_FILES['file1']['name']);
        
        if (move_uploaded_file($_FILES['file1']['tmp_name'], $uploadFile)) {
            echo "File uploaded successfully.";
        } else {
            echo "File upload failed.";
        }
    }
}
?>

2. 使用 AJAX 轮询上传进度

如果需要更精确的控制,可以结合后端进度查询:

前端代码:

代码语言:txt
复制
function uploadFile() {
    var formData = new FormData();
    var fileInput = document.getElementById('fileInput');
    var file = fileInput.files[0];
    var uploadId = 'upload_' + Date.now();
    
    formData.append('file', file);
    formData.append('upload_id', uploadId);
    
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'upload.php', true);
    
    // 启动上传
    xhr.send(formData);
    
    // 开始轮询进度
    var progressInterval = setInterval(function() {
        fetch('progress.php?upload_id=' + uploadId)
            .then(response => response.json())
            .then(data => {
                document.getElementById('progress').innerHTML = data.progress + '%';
                if (data.progress >= 100) {
                    clearInterval(progressInterval);
                }
            });
    }, 1000);
}

后端进度查询 (progress.php):

代码语言:txt
复制
<?php
session_start();

if (isset($_GET['upload_id'])) {
    $key = ini_get('session.upload_progress.prefix') . $_GET['upload_id'];
    if (!empty($_SESSION[$key])) {
        $progress = $_SESSION[$key];
        $percent = ($progress['bytes_processed'] / $progress['content_length']) * 100;
        echo json_encode(['progress' => round($percent, 2)]);
        exit;
    }
}

echo json_encode(['progress' => 0]);
?>

优势

  1. 用户体验提升:实时显示上传进度,避免用户误以为上传卡住
  2. 大文件支持:特别适合大文件上传场景
  3. 无需额外扩展:使用 PHP 内置功能实现

注意事项

  1. 确保服务器配置了足够的 post_max_sizeupload_max_filesize
  2. 对于超大文件,考虑分片上传方案
  3. 注意清理旧的进度信息,避免 session 膨胀
  4. 在生产环境中应考虑添加 CSRF 保护

常见问题及解决方案

问题1:进度不更新或卡住

  • 原因:可能是 session 锁或 AJAX 请求冲突
  • 解决:使用不同的 session 名称或优化 AJAX 轮询频率

问题2:进度显示不准确

  • 原因:网络延迟或服务器处理时间
  • 解决:增加轮询频率或使用 WebSocket 替代轮询

问题3:上传失败但进度显示100%

  • 原因:进度只跟踪上传过程,不包含服务器处理
  • 解决:在完成回调中验证服务器响应
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

领券