Javascript 使用jquery下载PHP cURL的进度
我不知道如何在每次使用php进行更新时推动进度。为了清楚起见,我将写一个例子 jQuery:Javascript 使用jquery下载PHP cURL的进度,javascript,php,jquery,curl,Javascript,Php,Jquery,Curl,我不知道如何在每次使用php进行更新时推动进度。为了清楚起见,我将写一个例子 jQuery: function uploadMovieDownload(link){ $.post("php/downloadmovie.php", { source:link }, function(json){ console.log(json); }); } uploadMovieDownload(url); PHP(PHP/downloadmovie.PHP): 我的问题是,它在完成后返回进度,而
function uploadMovieDownload(link){
$.post("php/downloadmovie.php", { source:link }, function(json){ console.log(json); });
}
uploadMovieDownload(url);
PHP(PHP/downloadmovie.PHP):
我的问题是,它在完成后返回进度,而不是在下载时推送进度。如果您有任何建议,请提前感谢。不要使用ob_flush(),只使用flush()。
(删除所有ob_uu功能)。
另外,考虑修改缓冲区大小:
curl_setopt($ch, CURLOPT_BUFFERSIZE, 16000);
尝试大小。完成所有脚本后,PHP将显示结果。这就是你刚刚完成进度的原因 您可以在后台执行curl下载,并将进度写入会话、数据库、会话或内存,如redis、memchche。然后在客户端,每隔很短的时间读取一次进程
您也可以使用Iframe来实现这一点。使用该方法,您将遇到各种缓存问题,php输出缓冲吗?你会有问题的。您是否在web服务器后面,比如nginx/apache/lighthttp/anything?你会有问题的。浏览器是否正在缓存输出?(所有主流浏览器都有),你会遇到问题 我建议一个没有这些问题的替代方案:使用$_会话存储下载百分比,并使用XMLHttpRequests查询百分比(实际上通过WebSocket查询百分比是最佳的、滞后的、使用较少的bw等,但实现起来要困难得多) 下载电影.php
<?php
require_once(dirname(__FILE__)."/functions.php");
$url = $_POST['source'];
$headers = getHeaders($url);
$url = $headers['url'];
//after validation of input
session_start();
$_SESSION['download_percentage']=0.0;//initialize it
session_write_close();
fastcgi_finish_request();//or if you're not using fcgi, some equivalent..
$path = dirname(__FILE__)."/temp/test.mp4";
$fp = fopen ($path, 'w+');
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
curl_setopt( $ch, CURLOPT_PROGRESSFUNCTION, 'progress' );
curl_setopt( $ch, CURLOPT_NOPROGRESS, false );
curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 100 );
curl_setopt( $ch, CURLOPT_FILE, $fp );
curl_exec( $ch );
curl_close( $ch );
fclose( $fp );
function progress($resource,$download_size, $downloaded, $upload_size, $uploaded){
$percentage=$download_size==0? 0.0 : (($downloaded/$download_size)*100);
session_start();
$_SESSION['download_percentage']=$percentage;
session_write_close();
}
引用自
echo”“;
回声“加载…”;
ob_flush();
冲洗();
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,”http://stackoverflow.com");
//curl_setopt($ch,CURLOPT_BUFFERSIZE,128);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_PROGRESSFUNCTION,'progress');
curl_setopt($ch,CURLOPT_NOPROGRESS,false);//需要使功能工作取得进展
curl_setopt($ch,CURLOPT_头,0);
curl_setopt($ch,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT');
$html=curl\u exec($ch);
卷曲关闭($ch);
功能进度($resource,$download\u size,$download,$upload\u size,$upload)
{
如果($download_size>0)
echo$download/$download_size*100;
ob_flush();
冲洗();
睡眠(1);//只是为了看看效果
}
回应“完成”;
ob_flush();
冲洗();
?>
您好,您有这个问题的解决方案吗……一些想法:1。负载平衡器可能会无意中保存渐进响应。2.您需要立即发送一定数量的字节,以使某些浏览器正常工作。3.您需要返回HTML,并将数据有条理地包装在
标记中,以使用这样一种简单的COMET方法。4.我会考虑使用一个临时文件来重新存储百分比,并用另一个简单的脚本来从文件中获取这个值,绕过上面的脚本。5.“SSE”,又名EventSource
是跨浏览器的,很容易在PHP中实现,以取代#4中的ping…我认为这是最好的解决方案,但不要忘记在每次更新后都需要使用session\u write\u close
,然后在更新之前再次使用session\u start
,否则,Ajax请求将被锁定,直到会话关闭为止,因为它将被锁定并阻止使用同一会话的后续请求。为什么要在if中包装会话\u start?它做的第一件事就是调用它?如果它知道加载它,请从cookie中检查会话\u id。@drew010哇。我不知道,谢谢!我会在一个小时内更新代码sec@MartinBarker我不知道在调用实际的php文件之前运行的是什么,但是一些站点在auto\u prepend\u file
php.ini指令或类似的x.x中开始会话。在这种情况下,调用session\u begin()而不检查它是否已经开始,将导致错误(我相信是E\u注意吗?)-刚刚检查过,是的:注意:会话已经启动-忽略第4行C:\WTServer\WWW\sesstest\2.php中的session\u start()
如果我尝试在没有会话启动的情况下使用$\u session,即使会话已经在其中,但对我不起作用,这会很奇怪。。。
<?php
require_once(dirname(__FILE__)."/functions.php");
$url = $_POST['source'];
$headers = getHeaders($url);
$url = $headers['url'];
//after validation of input
session_start();
$_SESSION['download_percentage']=0.0;//initialize it
session_write_close();
fastcgi_finish_request();//or if you're not using fcgi, some equivalent..
$path = dirname(__FILE__)."/temp/test.mp4";
$fp = fopen ($path, 'w+');
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
curl_setopt( $ch, CURLOPT_PROGRESSFUNCTION, 'progress' );
curl_setopt( $ch, CURLOPT_NOPROGRESS, false );
curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 100 );
curl_setopt( $ch, CURLOPT_FILE, $fp );
curl_exec( $ch );
curl_close( $ch );
fclose( $fp );
function progress($resource,$download_size, $downloaded, $upload_size, $uploaded){
$percentage=$download_size==0? 0.0 : (($downloaded/$download_size)*100);
session_start();
$_SESSION['download_percentage']=$percentage;
session_write_close();
}
<?php
if(""===session_id()){
session_start();
}
echo $_SESSION['download_percentage']??'?';
(function checkProgress() {
"use strict";
var xhr = new XMLHttpRequest();
xhr.open("GET", "getProgress.xhr.php");
xhr.addEventListener("readystatechange", function(ev) {
var xhr = ev.target;
if (xhr.readyState !== 4) {
return;
}
console.log(xhr.responseText + " percent downloaded!");
if (xhr.responseText === "100") {
return; /*stop checking for progress when its finished*/
}
setTimeout(checkProgress, 1000); //<<check for progress every 1 second
});
xhr.send();
})();
echo "<pre>";
echo "Loading ...";
ob_flush();
flush();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://stackoverflow.com");
//curl_setopt($ch, CURLOPT_BUFFERSIZE,128);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress');
curl_setopt($ch, CURLOPT_NOPROGRESS, false); // needed to make progress function work
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
$html = curl_exec($ch);
curl_close($ch);
function progress($resource,$download_size, $downloaded, $upload_size, $uploaded)
{
if($download_size > 0)
echo $downloaded / $download_size * 100;
ob_flush();
flush();
sleep(1); // just to see effect
}
echo "Done";
ob_flush();
flush();
?>