php+js+ajax技术实现在线更新并且显示进度条

在前不久我给我的程序写了一个在线更新的功能,这样用户就不用每次更新都需要下载安装包自己覆盖了,但是每次用户更新的时候会跳转到一个下载页面然后一直转啊转,如果更新包不大那倒是没有问题,几秒钟就下载好了,如果更新包太大了那么对于用户的体验就是非常的不好了,没有人喜欢对着一个转圈的页面。

所以我准备做一个在线更新并且可以显示更新的进度,使用的是原生的PHP和原生的JavaScript加上Ajax技术实现这个功能。这个是用的前后端分离,不用前后端分离我感觉应该要简单一点。
在这里插入图片描述

功能分析:

前端页面(ajax.html)+后端下载文件页面(wenjian.php)+后端获取文件下载进度页面(jindu.php)

后端两个页面直接用的文件和进度的拼音(真的捞)

  • 前端页面分析:

显示进度条框架:一个div中包含一个section,这个是用来实现进度的效果,div宽度和高度固定,section设置一个红色的背景颜色,高度和div一样,宽度为0。

  • 请求后端部分:

需要两个ajax请求,先请求后端下载文件的页面(wenjian.php),然后请求后端获取进度条的页面(jindu.php),获取进度这个请求我们需要用一个定时器来刷新它的进度。

后端页面分析:

  • 下载文件的页面(wenjian.php)分析:

我们需要前端发送一个用来存储进度的文件名,通过GET请求发送。
然后打开远程文件和本地文件,将远程文件读取然后写入本地文件。
while循环实现读取远程文件直到读取完成,读取一次就写入一次到本地文件,通过每次读取的字节和总字节和读取的次数,可以计算出读取的进度,公式如下:
读取的百分比进度 = 读取的次数*每次读取的字节数/总字节数
最后把百分比进度写入记录进度的文件里面。

  • 获取进度条的页面(jindu.php)分析:

读取记录进度文件的内容返回给前端即可。

最后附上代码
前端代码 ajax.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 100%;
            height: 50px;
            border: 1px solid grey;
        }

        section {
            width: 0;
            height: 100%;
            background-color: red;
            text-align: center;
            line-height: 100%;
            color: white;
            font-weight: 700;
        }
    </style>
</head>
<div>
    <section></section>
</div>

<body>

</body>
<script>
    let jd = Math.random(10);
    sec = document.querySelector('section');
    // 请求下载
    let xhr = new XMLHttpRequest();
    xhr.open('get', 'wenjian.php?jd='+jd, true);
    xhr.send();
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            if (xhr.status = 200) {
                console.log('下载成功');
                sec.style.width = '100%';
                sec.innerText = '100%';
                clearInterval(jindu);
            }
        }
    }
    // 获取下载进度
    let axhr = new XMLHttpRequest();
    var jindu = setInterval(function () {
        axhr.open('get', 'jindu.php?jd='+jd, true);
        axhr.send();
        axhr.onreadystatechange = function () {
            if (axhr.readyState == 4) {
                if (axhr.status = 200) {
                    var obj = JSON.parse(axhr.response);
                    var size = obj.size;
                    console.log(size);
                    if (size != '') {
                        if (size > 100) {
                            sec.style.width = '100%';
                            sec.innerText = '100%';
                        } else {
                            sec.style.width = size + '%';
                            sec.innerText = size + '%';
                        }
                    }
                }
            }
        }
    }, 10);
</script>

</html>

后端代码
wenjian.php:

<?php
ini_set('max_execution_time', '0');
$jd = $_GET['jd'];
//远程文件地址
$url = 'http://120.48.58.230/wp.zip';
// 打开远程文件
$remote = fopen($url, 'rb') or die('打开失败');
// 打开本地文件
$local = fopen('wp.zip', 'wb');
// 写入的次数i
$i = 0;
// 将远程文件写本地文件
while (!feof($remote)) {
    // 一次写入1024个字节 1kb;
    fwrite($local, fread($romete, 1024));
    $i++;
    // 计算下载的进度 (单位为字节 21064643是远程文件的字节)
    $n = $i * 1024 / 21064643;
    // 计算下载的百分比
    $n *= 100;
    echo $i;
    // 将下载进度写入进度文件
    file_put_contents($jd.'.txt',$n);
}
//删除进度文件
unlink($jd . '.txt');
fclose($local);
fclose($remote);
?>

jindu.php:

<?php
$jd = $_GET['jd'];
$jindu = file_get_contents($jd.'.txt');
$jindu = number_format($jindu,2);
echo json_encode(['size'=>$jindu]);
?>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现下载进度条,可以使用Ajax向服务器发送一个下载请求,并通过Ajax的回调函数来获取下载的进度信息。具体实现步骤如下: 1. 在HTML页面中添加一个进度条元素,比如使用Bootstrap中的进度条组件: ``` <div class="progress"> <div class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div> </div> ``` 2. 在JavaScript中使用Ajax向服务器发送一个下载请求,并设置对应的回调函数。在回调函数中,可以更新进度条进度: ``` $.ajax({ url: 'download.php', type: 'GET', dataType: 'json', xhrFields: { onprogress: function(e) { if (e.lengthComputable) { var percent = Math.round((e.loaded / e.total) * 100); $('.progress-bar').width(percent + '%'); $('.progress-bar').attr('aria-valuenow', percent); } } }, success: function(data) { // 下载完成后的处理 } }); ``` 3. 在服务器端的下载脚本中,需要设置正确的Content-Type和Content-Disposition头信息,以及使用chunked编码方式输出文件内容,这样才能让浏览器正确地获取下载进度信息: ``` header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="file.zip"'); header('Content-Transfer-Encoding: chunked'); header('Cache-Control: must-revalidate'); header('Pragma: public'); $buffer = 1024 * 8; $size = filesize($filepath); $handle = fopen($filepath, 'rb'); while (!feof($handle)) { $data = fread($handle, $buffer); echo $data; ob_flush(); flush(); } fclose($handle); ``` 这样就可以实现一个基于Ajax的下载进度条了。需要注意的是,不同的浏览器和服务器可能对于chunked编码方式有不同的支持,因此可能需要进行一些兼容性处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

创梦流浪人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值