为了账号安全,请及时绑定邮箱和手机立即绑定

从 SFTP 下载时如何向用户显示反馈?

从 SFTP 下载时如何向用户显示反馈?

PHP
守着星空守着你 2023-08-19 17:43:34
我有单击下载按钮时,下载文件大约需要 15 秒,因为它必须通过 SFTP 进入服务器,找到正确的路径/文件,然后返回响应download。超文本标记语言<a class="btn btn-primary btn-sm text-primary btn-download-1" onclick="startDownload('1')"><i class="fa fa-download "></i></a>注意:其中 1 是我知道它是哪个文件的关键......现在该按钮只会触发下面的这个功能function startDownload(interfaceId) {     window.location = "/nodes/interface/capture/download?port=" + interfaceId;         console.log(interfaceId); }它基本上刷新页面并调用下载路径/节点/界面/捕获/下载public function download_files(){    $dir = '';    $portNumber = Request::get('port');    $zipMe = false;    $remotePath = "/home/john/logs/".$dir."/";    if (!isset($dir) || $dir == null) {        return redirect()->back()->withInput()->withFlashDanger('SFTP Could not connect.');    }    $acsIp =  explode('://', env('ACS_URL'));    $acsIp =  explode(':',$acsIp[1])[0];    $sftp = new SFTP($acsIp.':22');    if (!$sftp->login('john', '***')) {        return redirect()->back()->withInput()->withFlashDanger('SFTP Could not connect.');    }    // Get into the Specified Directory    $sftpConn = Storage::disk('sftp');    $SFTPFiles = $sftpConn->allFiles('/'.$dir);    if ( count($SFTPFiles) > 0 ) {        foreach ($SFTPFiles as $file) {            $fileName = $file;            break;        }    } else {        \Log::info('Files Not found in the Remote!');        return redirect()->back()->withInput()->withFlashDanger('Files Not found in the Remote!');    }    // Create and give 777 permission to remote-files directory    if (!is_dir(public_path('remote-files/'.$dir))) {        mkdir(public_path('remote-files/'.$dir), 0777, true);    }    $filesToZip = [];    foreach ( $SFTPFiles as $fileName ) {        if ( $fileName == '..' || $fileName == '.' ) {            continue;        } else if ( $fileName == '' ) {            \Log::info('File not found');            continue;        }        }    }}结果它正在工作,但不知何故,它在那里停留了 15 秒,没有任何反馈。这真的很糟糕,用户不知道发生了什么。我想显示一个模式“正在下载,请不要关闭窗口”,但我不知道该怎么做,因为我必须使用 GET 下载文件。我现在有点卡住了。对我有什么建议吗?
查看完整描述

2 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

由于延迟是在服务器端,我相信你可以采取两种方法:


有一条路线来创建队列作业并确定进度,还有另一条路线供用户在服务器中下载下载的文件。用户每秒都会 ping 第一条路由以确定状态。


download_files()这个想法是在每次创建会话时生成一个唯一的 ID,将其存储在由路由和另一个路由共享的数组中,以启动download_files()和存储其结果。


例子:


$global_progress = array();

$global_files = array();


public function checkup_progress($id = null) {

    if ($id == null) {

        // this is new request, create job here

        $id = generate_id_func();

        download_file_job($id);

    } else if ($global_progress[$id] != "FINISHED") {

        // return $global_progress[$id] result

    } else {

        // finished, return download link

        // return route to "link_to_download_file/$id"

    }

}


public function download_file_job($id) {

    $global_progress[$id] = "NEW";

    // some code

    $global_progress[$id] = "IN PROGRESS (1)";

    // more code

    // more state here

    $global_files[$id] = $file;

    $global_progress[$id] = "FINISHED";

}


public function link_to_download_file($id) {

    // code here

    return Response::download($file, $onlyFileName, $headers);

}

如果您不想更改任何内容,可以使用 websocket,它会在几次操作后更新下载状态,并将文件发送到客户端。但这会受到文件大小的限制,因为 websocket 是在 javascript 中处理的,这意味着下载必须首先将 javascript 对象存储在浏览器内存中。


查看完整回答
反对 回复 2023-08-19
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

在进行重定向之前,显示一个包含您选择的消息的覆盖 div 。这不需要在服务器端执行任何操作。


function startDownload(interfaceId) {

    document.getElementById("overlay").style.display = "block"; // Show the overlay

    window.location = "/nodes/interface/capture/download?port=" + interfaceId;

    console.log(interfaceId);

}

CSS


#overlay {

  position: fixed; /* Sit on top of the page content */

  display: none; /* Hidden by default */

  width: 100%; /* Full width (cover the whole page) */

  height: 100%; /* Full height (cover the whole page) */

  top: 0;

  left: 0;

  right: 0;

  bottom: 0;

  background-color: rgba(0,0,0,0.5); /* Black background with opacity */

  z-index: 2; /* Specify a stack order in case you're using a different order for other elements */

  cursor: pointer; /* Add a pointer on hover */

  display: flex;

  justify-content: center;

  align-items: center;

  color: yellow;

}

超文本标记语言


<div id="overlay">

  Downloading is in progress, please don't close the window

</div> 



查看完整回答
反对 回复 2023-08-19
  • 2 回答
  • 0 关注
  • 119 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信