在进度元素上显示AJAX上传状态 [英] Show AJAX upload status on progress element

查看:51
本文介绍了在进度元素上显示AJAX上传状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个AJAX脚本将文件上传到PHP脚本,该脚本可能至少需要10秒钟才能运行.我想为用户显示进度.

I have an AJAX script to upload a file to a PHP script that is likely to take at least 10 seconds to run. I would like to display progress for it for the user.

在执行类中,我有一个属性 $ progress ,该属性随进度(在1-100中)更新,还有一个方法 get_progress()(目的是应该很明显.)

In the executing class, I have a property $progress which is updated with the progress (in 1-100), and a method get_progress() (which's purpose should be obvious).

问题是,如何更新前端的< progress> 元素供用户查看?

The question is, how to update the <progress> element on the front end for the user to see?

我认为AJAX是解决方案,但我只是无法解决.我无法到达相同的对象实例.

I think AJAX is the solution, but I just can not get my head around it. I can not get to the same object instance.

推荐答案

如果您的任务是上载庞大的数据集或在服务器上对其进行处理,则在向服务器更新进度时,您应该考虑进行某些作业架构,您可以在其中启动作业并使用服务器上运行的其他脚本来执行该作业(例如缩放/处理图像等).在这种情况下,您一次只能做一件事,因此形成了一个任务管道,其中有一个输入和一个最终处理的输出.

If your task is to upload a huge data-set or process it on the server, while updating progress to the server you should consider going with some sort of jobs architecture, where you initiate the job and do it with some other script running on the server (for example scaling / processing images etc). In this you do one thing at a time, thus forming a pipeline of tasks where there is an input and a final processed output.

在流水线的每个步骤中,任务状态都会在数据库中更新,然后可以通过现今存在的任何服务器推送机制将其发送给用户.运行用于处理上载和更新的单个脚本会给您的服务器带来负担,并且还会限制您(如果浏览器关闭,发生其他错误怎么办).将过程划分为多个步骤后,您可以从成功完成的点开始继续执行失败的任务.

At each step of pipeline the status of task is updated inside the database which can then be sent to the user by any server-push mechanism which exists these days. Running a single script which handles uploads and updates puts load on your server and also restricts you (what if the browser closes, what if some other error occurs). When process is divided into steps you can resume a failed task from the point where it succeeded last.

有很多方法可以做到这一点.但是整个流程看起来像这样

There exists many ways to do it. But the overall process flow looks like this

以下方法是我为个人项目所做的工作,此脚本非常适合将数千个高分辨率图像上传和处理到我的服务器上,然后将其缩小到多个版本并上传到Amazon s3,同时识别其中的对象.(我的原始代码在python中)

The following method is what I did for a personal project and this script held good for uploading and processing thousands of high resolution image to my server which then were scaled down into multiple versions and uploaded to amazon s3 while recognizing objects inside them. (My original code was in python)

启动运输或任务

首先上传您的内容,然后通过简单的POST请求立即为该交易返回交易ID或uuid.如果您要在任务中执行多个文件或执行多项操作,则可能还需要在此步骤中处理该逻辑

First Upload your content and then return a transaction id or uuid for this transaction immediately via a simple POST request. If you are doing multiple files or multiple things in the task, you may also want to handle that logic in this step

做好工作&返回进度.

Do the job & Return the progress.

弄清楚事务如何发生后,就可以使用任何服务器端推送技术来发送更新数据包.我会选择WebSocket或服务器已发送事件,只要适用于回溯到不受支持的浏览器上的长时间轮询.一个简单的SSE方法如下所示.

Once you have figured out how transactions occur you can then use any server side push technology to send update packet. I would choose WebSocket or Server Sent Events whichever applicable falling back to Long Polling on un-supported browsers. A simple SSE method would look like this.

function TrackProgress(upload_id){

    var progress = document.getElementById(upload_id);
    var source = new EventSource('/status/task/' + upload_id );

    source.onmessage = function (event) {
        var data = getData(event); // your custom method to get data, i am just using json here
        progress.setAttribute('value', data.filesDone );
        progress.setAttribute('max', data.filesTotal );
        progress.setAttribute('min', 0);
    };
}

request.post("/me/photos",{
    files: files
}).then(function(data){
     return data.upload_id;
}).then(TrackProgress);

在服务器端,您将需要创建一些东西来跟踪任务,带有job_id的简单Jobs体系结构和发送到db的进度就足够了.我将把作业调度和路由留给您,但是之后,概念代码如下所示(对于最简单的SSE,上面的代码就足够了).

On the server side, you will need to create something which keeps a track of the tasks, a simple Jobs architecture with job_id and progress sent to the db shall suffice. I would leave the job scheduling to you and the routing as well, but after that the conceptual code (for simplest SSE which will suffice the above code) is as follows.

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
/* Other code to take care of how do you find how many files are left 
   this is really not required */
function sendStatusViaSSE($task_id){
    $status = getStatus($task_id);
    $json_payload = array('filesDone' => $status.files_done,
                          'filesTotal' => $status.files_total);
    echo 'data: ' . json_encode( $json_payload ) . '\n\n';
    ob_flush();
    flush();

    // End of the game
    if( $status.done ){
        die();
    }

}

while( True ){
     sendStatusViaSSE( $request.$task_id );
     sleep(4);
}

?>

可以在此处找到关于SSE的很好的教程 http://html5doctor.com/server-sent-事件/

A good tutorial on SSE can be found here http://html5doctor.com/server-sent-events/

,您可以阅读有关以下问题的更多信息,从服务器推送更新从服务器推送更新

and you can read more about pushing updates from the server on this question Pushing updates from server

以上是概念上的解释,还有其他方法可以实现此目的,但是在我的案例中,这是解决了相当大任务的解决方案.

The above was a conceptual explanation, there are other ways to achieve this but this was the solution that took care of a fairly huge task in my case.

这篇关于在进度元素上显示AJAX上传状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆