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

使用纯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%

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

相关·内容

  • Retrofit2.3使用姊妹篇——带进度上传文件

    之前的一篇博客讲了Retrofit实现带进度下载的实现,算是Retrofit使用的“姐姐篇”,那今天我们就讲讲它的“妹妹篇“——用Retrofit实现带进度上传文件!...上传视频效果 这里我分别实现了图片和视频的上传,并附带有进度显示,为了更直观的展示上传效果,我写了图片选择和视频选择两个列表,将手机本地相册内的图片和视频全部展示出来(读取图片和视频的方法可以看这篇博客...demo里依然用的是自己简单封装的权限申请工具类,大家可以直接去看demo里的使用!...其中我们在上传进度的回调中返回进度的百分比,在此可以将进度显示在控件上。如果你还有一些个性化的需求,可以自行添加。 四、网络工具类准备 对Retrofit进行简单封装。...,但是它提供了RequestBody 类,我们通过继承RequestBody类,重写writeTo方法即可获取上传进度!

    2.7K10

    PHP中AJAX的使用(完整实例【大牛可飘过】)

    首先你得NEW一个AJAX的对象,类必须得事例化才能使用,这个大家都知道对吧     第一步:var oAjax = new XMLHttpRequest();     但是为了兼容IE6这么蛋疼的浏览器一般这么写...2.第二步咱得给服务器连接起来吧,这是必须的啊;   用open();用法是这样的:open(传输方式,文件地址,同步还是异步(默认异步))     oAjax.open('get','ajax.php...oAjax); 28 //2.连接服务器 29 //open(传输方式,文件地址,同步还是异步(默认异步)) 30 oAjax.open('get','ajax.php...代码ajax.php 1 php 2 $hehe=$_GET['hehe']; 3 echo $hehe; 4 ?> 简单的AJAX用法事例到此为止,特为初学者而写,大牛可飘过……

    1.3K80

    PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解

    本文实例讲述了PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作。...分享给大家供大家参考,具体如下: 2019-07-04更新 更新修改原因: 前台界面ui显示不好看 后台处理逻辑混乱,涉及到多张图片处理起来很麻烦,所以修改成通过ajax上传/删除图片。...contentType: false, // 告诉jQuery不要去设置Content-Type请求头(发送数据到服务器时所使用的内容类型。...参考: JavaScript实现图片上传并预览并提交ajax PHP 代码: //ajax上传图片 public function upimg() { $file = request()->file...$cate['pic']); } } else { // 上传失败获取错误信息 $this->error($file->getError()); } } 希望本文所述对大家PHP程序设计有所帮助

    1.5K20

    纯血鸿蒙APP实战开发——使用绘制组件实现自定义进度动画

    介绍本示例介绍使用绘制组件中的Circle组件以及Path组件实现实时进度效果。该场景多用于手机电池电量、汽车油量、水位变化等动态变化中。...效果预览图使用说明加载完成后初始显示进度为0%,颜色为红色,且有充电、耗电两个按钮。点击充电按钮,进度会持续增长,直到100%时绿色填充满整个圆形,当到达20%以上和80%以上时,颜色动态变化。...点击耗电按钮,进度会持续下降,直到0%恢复1中的初始效果,当到达20%以下和80%以下时,颜色动态变化。实现思路使用Circle组件绘制外层的圆环。...中间的填充有两个状态:1、在进度100%时是填充颜色的圆形;2、在进度不足100%时,使用Path组件绘制闭合曲线实现。...:知识点:使用Path组件绘制封闭曲线,实现水位线效果Path() .width(Constants.DIAMETER) .height(Constants.DIAMETER) .commands

    14920

    MVC5:使用Ajax和HTML5实现文件上传功能

    引言 在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能。...增加了上传/下载二进制数据 2. 增加了上传过程中Progess (进度条)事件,该事件包含多部分的信息: Total:整型值,用于指定传输数据的总字节数。...跨资源共享请求 这些新特性都使得Ajax和HTML5很好的协作,让文件上传变得非常简单,不再需要使用Flash Player、外部插件或html的标签就可以完成,根据服务器端就可以显示上传进度条...本文会编写一个小型应用程序,能够实现以下功能: 上传单个文件,提供上传进度信息显示。 将图片发送到服务器时,创建图像缩略图。 通过文件列表或拖拽操作实现多个文件上传。...编写代码 如何上传单个文件并显示上传进度? 首先需要做的是创建简单的View : 定义一个表单,由输入文件元素和提交按钮组成。 使用Bootstrap 进度条显示进度。

    4.5K101

    使用Fusioncharts实现后台处理进度的前台展示

    本文要解决两个问题: 1、在ajax的数据交互中,如何获得后台的处理进度? 2、在前台界面中,如何使用图形化的方式展示后台处理进度? 关于第一个问题,不是本文的重点,简单说一下思路。...PHP中提供了 flush() 和 ob_flush() 函数,允许用户将缓存的内容输出,但是如果在服务器端使用了gzip压缩,这种方法常常会失效。...完成后的效果如下图,用户选择一个Zip文件包进行上传,JS完成后台上传、解压缩与文件处理的操作。使用FusionCharts进行图形化的进度显示。 ?...因为我的后台处理过程都是在领带的ajax请求中完成的,所以采取了一个折衷的办法,ajax请求完成后,将进度写入到cookie中,然后FusionCharts定时从cookie中读取进度来进行展示。...注:我使用的版本是Fusion Charts Suite XT 参考资料: 1、Fusion Charts Linear Gauge 2、AjaxFileUpload 3、实现jQuery的Ajax文件上传

    1.4K10
    领券